Implemented new PIN unlock design

The pin unlock design was changed according to the spec
and new animations where introduced for the password field.

Bug: 13735707
Change-Id: I76f5e873bd0ea4f34ca3d2cd971223f0a83e2f28
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index e7e750d..c2e1b96 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7001,11 +7001,6 @@
         <attr name="layout_maxHeight" />
     </declare-styleable>
 
-    <declare-styleable name="NumPadKey">
-        <attr name="digit" format="integer" />
-        <attr name="textView" format="reference" />
-    </declare-styleable>
-
     <declare-styleable name="Toolbar">
         <attr name="titleTextAppearance" format="reference" />
         <attr name="subtitleTextAppearance" format="reference" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index d6be3133..5055854 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -2583,33 +2583,6 @@
         <item name="android:externalRouteEnabledDrawable">@drawable/ic_media_route_holo_light</item>
     </style>
 
-    <!-- Keyguard PIN pad styles -->
-    <style name="Widget.Button.NumPadKey"
-            parent="@android:style/Widget.Button">
-        <item name="android:singleLine">true</item>
-        <item name="android:gravity">left|center_vertical</item>
-        <item name="android:background">?android:attr/selectableItemBackground</item>
-        <item name="android:textSize">34dp</item>
-        <item name="android:fontFamily">sans-serif</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">#ffffff</item>
-        <item name="android:paddingBottom">10dp</item>
-        <item name="android:paddingLeft">20dp</item>
-    </style>
-    <style name="TextAppearance.NumPadKey"
-            parent="@android:style/TextAppearance">
-        <item name="android:textSize">34dp</item>
-        <item name="android:fontFamily">sans-serif</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">#ffffff</item>
-    </style>
-    <style name="TextAppearance.NumPadKey.Klondike">
-        <item name="android:textSize">20dp</item>
-        <item name="android:fontFamily">sans-serif-condensed</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">#80ffffff</item>
-    </style>
-
     <style name="TextAppearance.TimePicker.TimeLabel" parent="TextAppearance">
     </style>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7442459..dac3352 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1431,9 +1431,6 @@
   <java-symbol type="style" name="Animation.LockScreen" />
   <java-symbol type="style" name="Theme.Dialog.RecentApplications" />
   <java-symbol type="style" name="Theme.ExpandedMenu" />
-  <java-symbol type="style" name="Widget.Button.NumPadKey" />
-  <java-symbol type="style" name="TextAppearance.NumPadKey" />
-  <java-symbol type="style" name="TextAppearance.NumPadKey.Klondike" />
 
   <!-- From services -->
   <java-symbol type="anim" name="screen_rotate_0_enter" />
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_done_wht.png b/packages/Keyguard/res/drawable-hdpi/ic_done_wht.png
new file mode 100644
index 0000000..82c01ef
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_done_wht.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_input_delete.png b/packages/Keyguard/res/drawable-hdpi/ic_input_delete.png
deleted file mode 100644
index 5d638bd..0000000
--- a/packages/Keyguard/res/drawable-hdpi/ic_input_delete.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_done_wht.png b/packages/Keyguard/res/drawable-mdpi/ic_done_wht.png
new file mode 100644
index 0000000..8c16930
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_done_wht.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_input_delete.png b/packages/Keyguard/res/drawable-mdpi/ic_input_delete.png
deleted file mode 100644
index 47c8708..0000000
--- a/packages/Keyguard/res/drawable-mdpi/ic_input_delete.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_done_wht.png b/packages/Keyguard/res/drawable-xhdpi/ic_done_wht.png
new file mode 100644
index 0000000..6a4d8a7
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_done_wht.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_input_delete.png b/packages/Keyguard/res/drawable-xhdpi/ic_input_delete.png
deleted file mode 100644
index 8b822d9..0000000
--- a/packages/Keyguard/res/drawable-xhdpi/ic_input_delete.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/ic_done_wht.png b/packages/Keyguard/res/drawable-xxhdpi/ic_done_wht.png
new file mode 100644
index 0000000..4c04ba2
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/ic_done_wht.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxxhdpi/ic_done_wht.png b/packages/Keyguard/res/drawable-xxxhdpi/ic_done_wht.png
new file mode 100644
index 0000000..bd6c4df
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxxhdpi/ic_done_wht.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable/ic_backspace_24dp.xml b/packages/Keyguard/res/drawable/ic_backspace_24dp.xml
new file mode 100644
index 0000000..9e5016d
--- /dev/null
+++ b/packages/Keyguard/res/drawable/ic_backspace_24dp.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+    <size
+        android:width="24dp"
+        android:height="24dp"/>
+
+    <viewport
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
+
+    <path
+        android:fill="#ffffffff"
+        android:pathData="M44.0,6.0L14.0,6.0c-1.4,0.0 -2.5,0.7 -3.2,1.8L0.0,24.0l10.8,16.2c0.7,1.1 1.8,1.8 3.2,1.8l30.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L48.0,10.0C48.0,7.8 46.2,6.0 44.0,6.0zM38.0,31.2L35.2,34.0L28.0,26.8L20.8,34.0L18.0,31.2l7.2,-7.2L18.0,16.8l2.8,-2.8l7.2,7.2l7.2,-7.2l2.8,2.8L30.8,24.0L38.0,31.2z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ripple_drawable.xml b/packages/Keyguard/res/drawable/ripple_drawable.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/ripple_drawable.xml
rename to packages/Keyguard/res/drawable/ripple_drawable.xml
diff --git a/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml b/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml
deleted file mode 100644
index 49b4212..0000000
--- a/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- This is the host view that generally contains two sub views: the widget view
-    and the security view. -->
-<com.android.keyguard.KeyguardSimpleHostView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/keyguard_host_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <com.android.keyguard.KeyguardSecurityContainer
-        android:id="@+id/keyguard_security_container"
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/keyguard_security_height"
-        android:clipChildren="false"
-        android:clipToPadding="false"
-        android:padding="0dp"
-        android:layout_gravity="center">
-        <com.android.keyguard.KeyguardSecurityViewFlipper
-            android:id="@+id/view_flipper"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:clipChildren="false"
-            android:clipToPadding="false"
-            android:paddingTop="@dimen/keyguard_security_view_margin"
-            android:gravity="center">
-        </com.android.keyguard.KeyguardSecurityViewFlipper>
-    </com.android.keyguard.KeyguardSecurityContainer>
-
-</com.android.keyguard.KeyguardSimpleHostView>
-
diff --git a/packages/Keyguard/res/layout/keyguard_bouncer.xml b/packages/Keyguard/res/layout/keyguard_bouncer.xml
index 489c5f5..c85f04c 100644
--- a/packages/Keyguard/res/layout/keyguard_bouncer.xml
+++ b/packages/Keyguard/res/layout/keyguard_bouncer.xml
@@ -16,7 +16,8 @@
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:background="@android:color/transparent" >
 
     <include
         style="@style/BouncerSecurityContainer"
diff --git a/packages/Keyguard/res/layout/keyguard_num_pad_key.xml b/packages/Keyguard/res/layout/keyguard_num_pad_key.xml
new file mode 100644
index 0000000..72591d46
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_num_pad_key.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <TextView
+        android:id="@+id/digit_text"
+        style="@style/Widget.TextView.NumPadKey"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        />
+    <TextView
+        android:id="@+id/klondike_text"
+        style="@style/Widget.TextView.NumPadKey.Klondike"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        />
+</merge>
+
diff --git a/packages/Keyguard/res/layout/keyguard_pin_view.xml b/packages/Keyguard/res/layout/keyguard_pin_view.xml
index a8e330b..a33f95b 100644
--- a/packages/Keyguard/res/layout/keyguard_pin_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_pin_view.xml
@@ -18,215 +18,202 @@
 -->
 
 <com.android.keyguard.KeyguardPINView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/keyguard_pin_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
-    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
-    android:orientation="vertical"
-    android:contentDescription="@string/keyguard_accessibility_pin_unlock"
-    >
-    <include layout="@layout/keyguard_message_area"
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:androidprv="http://schemas.android.com/apk/res-auto"
+        android:id="@+id/keyguard_pin_view"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        />
+        android:layout_height="match_parent"
+        androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+        androidprv:layout_maxHeight="@dimen/keyguard_security_max_height"
+        android:orientation="vertical"
+        android:contentDescription="@string/keyguard_accessibility_pin_unlock"
+        >
+    <include layout="@layout/keyguard_message_area"
+             android:layout_width="match_parent"
+             android:layout_height="wrap_content"
+            />
     <LinearLayout
-       android:id="@+id/keyguard_bouncer_frame"
-       android:background="@drawable/kg_bouncer_bg_white"
-       android:layout_width="match_parent"
-       android:layout_height="0dp"
-       android:orientation="vertical"
-       android:layout_weight="1"
-       android:layoutDirection="ltr"
-       >
-       <RelativeLayout
-          android:id="@+id/row0"
-          android:layout_width="match_parent"
-          android:layout_height="0dp"
-          android:layout_weight="1"
-          >
-          <ImageButton android:id="@+id/delete_button"
-               android:layout_width="wrap_content"
-               android:layout_height="match_parent"
-               android:layout_alignParentEnd="true"
-               android:gravity="center_vertical"
-               android:src="@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"
-               />
-           <TextView android:id="@+id/pinEntry"
-               android:editable="true"
-               android:layout_width="match_parent"
-               android:layout_height="match_parent"
-               android:layout_toStartOf="@+id/delete_button"
-               android:layout_alignParentStart="true"
-               android:gravity="center"
-               android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
-               android:singleLine="true"
-               android:cursorVisible="false"
-               android:background="@null"
-               android:textAppearance="@style/TextAppearance.NumPadKey"
-               android:imeOptions="flagForceAscii|actionDone"
-               />
+            android:id="@+id/keyguard_bouncer_frame"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:orientation="vertical"
+            android:layout_weight="1"
+            android:layoutDirection="ltr"
+            >
+        <RelativeLayout
+                android:id="@+id/row0"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:paddingBottom="16dp"
+                >
+            <com.android.keyguard.PasswordTextView
+                    android:id="@+id/pinEntry"
+                    android:layout_width="@dimen/keyguard_security_width"
+                    android:layout_height="match_parent"
+                    android:gravity="center"
+                    android:layout_centerHorizontal="true"
+                    android:layout_marginRight="72dp"
+                    androidprv:scaledTextSize="28"
+                    />
+            <ImageButton
+                    android:id="@+id/delete_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:gravity="center_vertical"
+                    android:src="@drawable/ic_backspace_24dp"
+                    android:clickable="true"
+                    android:paddingTop="8dip"
+                    android:paddingBottom="8dip"
+                    android:paddingRight="8dp"
+                    android:paddingLeft="24dp"
+                    android:background="@drawable/ripple_drawable"
+                    android:contentDescription="@string/keyboardview_keycode_delete"
+                    android:layout_alignEnd="@+id/pinEntry"
+                    android:layout_alignParentRight="true"
+                    />
             <View
-               android:id="@+id/divider"
-               android:layout_width="match_parent"
-               android:layout_height="1dp"
-               android:layout_alignParentBottom="true"
-               android:background="#55FFFFFF"
-               />
-       </RelativeLayout>
-       <LinearLayout
-           android:id="@+id/row1"
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:layout_weight="1"
-           android:orientation="horizontal"
-           >
-           <view class="com.android.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.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.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:id="@+id/row2"
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:layout_weight="1"
-           android:orientation="horizontal"
-           >
-           <view class="com.android.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.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.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:id="@+id/row3"
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:orientation="horizontal"
-           android:layout_weight="1"
-           >
-           <view class="com.android.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.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.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:id="@+id/row4"
-           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.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>
+                    android:id="@+id/divider"
+                    android:layout_width="match_parent"
+                    android:layout_height="1dp"
+                    android:layout_alignParentBottom="true"
+                    android:background="#28FFFFFF"
+                    />
+        </RelativeLayout>
+        <LinearLayout
+                android:id="@+id/row1"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:orientation="horizontal"
+                >
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key1"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pinEntry"
+                    androidprv:digit="1"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key2"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pinEntry"
+                    androidprv:digit="2"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key3"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pinEntry"
+                    androidprv:digit="3"
+                    />
+        </LinearLayout>
+        <LinearLayout
+                android:id="@+id/row2"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:orientation="horizontal"
+                >
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key4"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pinEntry"
+                    androidprv:digit="4"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key5"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pinEntry"
+                    androidprv:digit="5"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key6"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pinEntry"
+                    androidprv:digit="6"
+                    />
+        </LinearLayout>
+        <LinearLayout
+                android:id="@+id/row3"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:orientation="horizontal"
+                android:layout_weight="1"
+                >
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key7"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pinEntry"
+                    androidprv:digit="7"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key8"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pinEntry"
+                    androidprv:digit="8"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key9"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pinEntry"
+                    androidprv:digit="9"
+                    />
+        </LinearLayout>
+        <LinearLayout
+                android:id="@+id/row4"
+                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"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key0"
+                    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"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:paddingBottom="11sp"
+                    android:src="@drawable/ic_done_wht"
+                    android:background="@drawable/ripple_drawable"
+                    android:contentDescription="@string/keyboardview_keycode_enter"
+                    />
+        </LinearLayout>
     </LinearLayout>
     <include layout="@layout/keyguard_eca"
-                   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" />
+             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"/>
 
 </com.android.keyguard.KeyguardPINView>
diff --git a/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml b/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml
index e167817..4f35daf 100644
--- a/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml
@@ -18,213 +18,205 @@
 -->
 <!-- This is the SIM PIN view that allows the user to enter a SIM PIN to unlock the device. -->
 <com.android.keyguard.KeyguardSimPinView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/keyguard_sim_pin_view"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
-    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
-    android:gravity="center_horizontal">
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:androidprv="http://schemas.android.com/apk/res-auto"
+        android:id="@+id/keyguard_sim_pin_view"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+        androidprv:layout_maxHeight="@dimen/keyguard_security_max_height"
+        android:gravity="center_horizontal"
+        android:contentDescription="@string/keyguard_accessibility_pin_unlock">
 
     <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:src="@drawable/ic_lockscreen_sim"/>
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_lockscreen_sim"/>
 
     <include layout="@layout/keyguard_message_area"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        />
+             android:layout_width="match_parent"
+             android:layout_height="wrap_content"
+            />
     <LinearLayout
-       android:id="@+id/keyguard_bouncer_frame"
-       android:background="@drawable/kg_bouncer_bg_white"
-       android:layout_width="match_parent"
-       android:layout_height="0dp"
-       android:orientation="vertical"
-       android:layout_weight="1"
-       android:layoutDirection="ltr"
-       >
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:orientation="horizontal"
-           android:layout_weight="1"
-           >
-           <TextView android:id="@+id/simPinEntry"
-               android:editable="true"
-               android:layout_width="0dip"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               android:gravity="center"
-               android:layout_marginStart="@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="@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.keyguard.NumPadKey"
-               android:id="@+id/key1"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/simPinEntry"
-               androidprv:digit="1"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key2"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/simPinEntry"
-               androidprv:digit="2"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key3"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/simPinEntry"
-               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.keyguard.NumPadKey"
-               android:id="@+id/key4"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/simPinEntry"
-               androidprv:digit="4"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key5"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/simPinEntry"
-               androidprv:digit="5"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key6"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/simPinEntry"
-               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.keyguard.NumPadKey"
-               android:id="@+id/key7"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/simPinEntry"
-               androidprv:digit="7"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key8"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/simPinEntry"
-               androidprv:digit="8"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key9"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/simPinEntry"
-               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.keyguard.NumPadKey"
-               android:id="@+id/key0"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/simPinEntry"
-               androidprv:digit="0"
-               />
-           <ImageButton
-               android:id="@+id/key_enter"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               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>
+            android:id="@+id/keyguard_bouncer_frame"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:orientation="vertical"
+            android:layout_weight="1"
+            android:layoutDirection="ltr"
+            >
+        <RelativeLayout
+                android:id="@+id/row0"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:paddingBottom="16dp"
+                >
+            <com.android.keyguard.PasswordTextView
+                    android:id="@+id/simPinEntry"
+                    android:layout_width="@dimen/keyguard_security_width"
+                    android:layout_height="match_parent"
+                    android:gravity="center"
+                    android:layout_centerHorizontal="true"
+                    android:layout_marginRight="72dp"
+                    androidprv:scaledTextSize="28"
+                    />
+            <ImageButton
+                    android:id="@+id/delete_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:gravity="center_vertical"
+                    android:src="@drawable/ic_backspace_24dp"
+                    android:clickable="true"
+                    android:paddingTop="8dip"
+                    android:paddingBottom="8dip"
+                    android:paddingRight="8dp"
+                    android:paddingLeft="24dp"
+                    android:background="@drawable/ripple_drawable"
+                    android:contentDescription="@string/keyboardview_keycode_delete"
+                    android:layout_alignEnd="@+id/pinEntry"
+                    android:layout_alignParentRight="true"
+                    />
+            <View
+                    android:id="@+id/divider"
+                    android:layout_width="match_parent"
+                    android:layout_height="1dp"
+                    android:layout_alignParentBottom="true"
+                    android:background="#28FFFFFF"
+                    />
+        </RelativeLayout>
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:orientation="horizontal"
+                >
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key1"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/simPinEntry"
+                    androidprv:digit="1"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key2"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/simPinEntry"
+                    androidprv:digit="2"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key3"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/simPinEntry"
+                    androidprv:digit="3"
+                    />
+        </LinearLayout>
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:orientation="horizontal"
+                >
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key4"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/simPinEntry"
+                    androidprv:digit="4"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key5"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/simPinEntry"
+                    androidprv:digit="5"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key6"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/simPinEntry"
+                    androidprv:digit="6"
+                    />
+        </LinearLayout>
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:orientation="horizontal"
+                android:layout_weight="1"
+                >
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key7"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/simPinEntry"
+                    androidprv:digit="7"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key8"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/simPinEntry"
+                    androidprv:digit="8"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key9"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/simPinEntry"
+                    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"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key0"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/simPinEntry"
+                    androidprv:digit="0"
+                    />
+            <ImageButton
+                    android:id="@+id/key_enter"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:paddingBottom="11sp"
+                    android:src="@drawable/ic_done_wht"
+                    android:background="@drawable/ripple_drawable"
+                    android:contentDescription="@string/keyboardview_keycode_enter"
+                    />
+        </LinearLayout>
     </LinearLayout>
 
     <include layout="@layout/keyguard_eca"
-                   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" />
+             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"/>
 
 </com.android.keyguard.KeyguardSimPinView>
diff --git a/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml b/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml
index ac798ca..41484e2 100644
--- a/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml
@@ -19,212 +19,203 @@
 <!-- This is the SIM PUK view that allows the user to recover their device by entering the
     carrier-provided PUK code and entering a new SIM PIN for it. -->
 <com.android.keyguard.KeyguardSimPukView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/keyguard_sim_puk_view"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
-    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
-    android:gravity="center_horizontal">
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:androidprv="http://schemas.android.com/apk/res-auto"
+        android:id="@+id/keyguard_sim_puk_view"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+        androidprv:layout_maxHeight="@dimen/keyguard_security_max_height"
+        android:gravity="center_horizontal">
 
     <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:src="@drawable/ic_lockscreen_sim"/>
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_lockscreen_sim"/>
 
     <include layout="@layout/keyguard_message_area"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        />
+             android:layout_width="match_parent"
+             android:layout_height="wrap_content"
+            />
     <LinearLayout
-       android:id="@+id/keyguard_bouncer_frame"
-       android:background="@drawable/kg_bouncer_bg_white"
-       android:layout_width="match_parent"
-       android:layout_height="0dp"
-       android:orientation="vertical"
-       android:layout_weight="1"
-       android:layoutDirection="ltr"
-       >
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:orientation="horizontal"
-           android:layout_weight="1"
-           >
-           <TextView android:id="@+id/pukEntry"
-               android:editable="true"
-               android:layout_width="0dip"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               android:gravity="center"
-               android:layout_marginStart="@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="@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.keyguard.NumPadKey"
-               android:id="@+id/key1"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pukEntry"
-               androidprv:digit="1"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key2"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pukEntry"
-               androidprv:digit="2"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key3"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pukEntry"
-               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.keyguard.NumPadKey"
-               android:id="@+id/key4"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pukEntry"
-               androidprv:digit="4"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key5"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pukEntry"
-               androidprv:digit="5"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key6"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pukEntry"
-               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.keyguard.NumPadKey"
-               android:id="@+id/key7"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pukEntry"
-               androidprv:digit="7"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key8"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pukEntry"
-               androidprv:digit="8"
-               />
-           <view class="com.android.keyguard.NumPadKey"
-               android:id="@+id/key9"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pukEntry"
-               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.keyguard.NumPadKey"
-               android:id="@+id/key0"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pukEntry"
-               androidprv:digit="0"
-               />
-           <ImageButton
-               android:id="@+id/key_enter"
-               style="@style/Widget.Button.NumPadKey.Sim"
-               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>
+            android:id="@+id/keyguard_bouncer_frame"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:orientation="vertical"
+            android:layout_weight="1"
+            android:layoutDirection="ltr"
+            >
+        <RelativeLayout
+                android:id="@+id/row0"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:paddingBottom="16dp"
+                >
+            <com.android.keyguard.PasswordTextView
+                    android:id="@+id/pukEntry"
+                    android:layout_width="@dimen/keyguard_security_width"
+                    android:layout_height="match_parent"
+                    android:gravity="center"
+                    android:layout_centerHorizontal="true"
+                    android:layout_marginRight="72dp"
+                    androidprv:scaledTextSize="28"
+                    />
+            <ImageButton
+                    android:id="@+id/delete_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:gravity="center_vertical"
+                    android:src="@drawable/ic_backspace_24dp"
+                    android:clickable="true"
+                    android:paddingTop="8dip"
+                    android:paddingBottom="8dip"
+                    android:paddingRight="8dp"
+                    android:paddingLeft="24dp"
+                    android:background="@drawable/ripple_drawable"
+                    android:contentDescription="@string/keyboardview_keycode_delete"
+                    android:layout_alignEnd="@+id/pinEntry"
+                    android:layout_alignParentRight="true"
+                    />
+            <View
+                    android:id="@+id/divider"
+                    android:layout_width="match_parent"
+                    android:layout_height="1dp"
+                    android:layout_alignParentBottom="true"
+                    android:background="#28FFFFFF"
+                    />
+        </RelativeLayout>
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:orientation="horizontal"
+                >
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key1"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pukEntry"
+                    androidprv:digit="1"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key2"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pukEntry"
+                    androidprv:digit="2"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key3"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pukEntry"
+                    androidprv:digit="3"
+                    />
+        </LinearLayout>
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:orientation="horizontal"
+                >
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key4"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pukEntry"
+                    androidprv:digit="4"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key5"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pukEntry"
+                    androidprv:digit="5"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key6"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pukEntry"
+                    androidprv:digit="6"
+                    />
+        </LinearLayout>
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:orientation="horizontal"
+                android:layout_weight="1"
+                >
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key7"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pukEntry"
+                    androidprv:digit="7"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key8"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pukEntry"
+                    androidprv:digit="8"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key9"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pukEntry"
+                    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"
+                    />
+            <com.android.keyguard.NumPadKey
+                    android:id="@+id/key0"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    androidprv:textView="@+id/pukEntry"
+                    androidprv:digit="0"
+                    />
+            <ImageButton
+                    android:id="@+id/key_enter"
+                    android:layout_width="0px"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:paddingBottom="11sp"
+                    android:src="@drawable/ic_done_wht"
+                    android:background="@drawable/ripple_drawable"
+                    android:contentDescription="@string/keyboardview_keycode_enter"
+                    />
+        </LinearLayout>
     </LinearLayout>
 
     <include layout="@layout/keyguard_eca"
-                   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" />
+             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"/>
 </com.android.keyguard.KeyguardSimPukView>
diff --git a/packages/Keyguard/res/layout-port/keyguard_simple_host_view.xml b/packages/Keyguard/res/layout/keyguard_simple_host_view.xml
similarity index 93%
rename from packages/Keyguard/res/layout-port/keyguard_simple_host_view.xml
rename to packages/Keyguard/res/layout/keyguard_simple_host_view.xml
index ed600b0..4336e1c 100644
--- a/packages/Keyguard/res/layout-port/keyguard_simple_host_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_simple_host_view.xml
@@ -29,7 +29,8 @@
     <com.android.keyguard.KeyguardSecurityContainer
         android:id="@+id/keyguard_security_container"
         android:layout_width="wrap_content"
-        android:layout_height="@dimen/keyguard_security_height"
+        android:layout_height="wrap_content"
+        androidprv:layout_maxHeight="@dimen/keyguard_security_max_height"
         android:clipChildren="false"
         android:clipToPadding="false"
         android:padding="0dp"
diff --git a/packages/Keyguard/res/values/arrays.xml b/packages/Keyguard/res/values/arrays.xml
index 550f80c..291f776 100644
--- a/packages/Keyguard/res/values/arrays.xml
+++ b/packages/Keyguard/res/values/arrays.xml
@@ -79,7 +79,7 @@
 
     <!-- list of 3- or 4-letter mnemonics for a 10-key numeric keypad -->
     <string-array translatable="false" name="lockscreen_num_pad_klondike">
-        <item></item><!-- 0 -->
+        <item>+</item><!-- 0 -->
         <item></item><!-- 1 -->
         <item>ABC</item><!-- 2 -->
         <item>DEF</item><!-- 3 -->
diff --git a/packages/Keyguard/res/values/attrs.xml b/packages/Keyguard/res/values/attrs.xml
index 2410b6a..9100140 100644
--- a/packages/Keyguard/res/values/attrs.xml
+++ b/packages/Keyguard/res/values/attrs.xml
@@ -134,6 +134,10 @@
         <attr name="textView" format="reference" />
     </declare-styleable>
 
+    <declare-styleable name="PasswordTextView">
+        <attr name="scaledTextSize" format="integer" />
+    </declare-styleable>
+
     <declare-styleable name="CarrierText">
         <attr name="allCaps" format="boolean" />
     </declare-styleable>
diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml
index 4b113ff..375cf32 100644
--- a/packages/Keyguard/res/values/dimens.xml
+++ b/packages/Keyguard/res/values/dimens.xml
@@ -119,6 +119,9 @@
     <!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
     <dimen name="keyguard_security_height">400dp</dimen>
 
+    <!-- Max Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+    <dimen name="keyguard_security_max_height">460dp</dimen>
+
     <!-- Margin around the various security views -->
     <dimen name="keyguard_security_view_margin">8dp</dimen>
 
@@ -164,6 +167,12 @@
     <!-- The y translation to apply at the start in appear animations. -->
     <dimen name="appear_y_translation_start">32dp</dimen>
 
+    <!-- The size of the dots in the PIN unlock method. -->
+    <dimen name="password_dot_size">9dp</dimen>
+
+    <!-- The padding between chars of the password view. -->
+    <dimen name="password_char_padding">8dp</dimen>
+
     <!-- The vertical margin between the date and the owner info. -->
     <dimen name="date_owner_info_margin">10dp</dimen>
 </resources>
diff --git a/packages/Keyguard/res/values/styles.xml b/packages/Keyguard/res/values/styles.xml
index 11142cf..cdd6489 100644
--- a/packages/Keyguard/res/values/styles.xml
+++ b/packages/Keyguard/res/values/styles.xml
@@ -19,36 +19,20 @@
 
 <resources>
     <!-- Keyguard PIN pad styles -->
-    <style name="Widget.Button.NumPadKey"
-            parent="@android:style/Widget.Button">
+    <style name="Widget.TextView.NumPadKey" parent="@android:style/Widget.TextView">
         <item name="android:singleLine">true</item>
-        <item name="android:gravity">left|center_vertical</item>
-        <item name="android:background">?android:attr/selectableItemBackground</item>
-        <item name="android:textSize">34dp</item>
+        <item name="android:gravity">center_horizontal|center_vertical</item>
+        <item name="android:background">@null</item>
+        <item name="android:textSize">36sp</item>
+        <item name="android:fontFamily">sans-serif-light</item>
+        <item name="android:textColor">#ffffffff</item>
+        <item name="android:paddingBottom">-16dp</item>
+    </style>
+    <style name="Widget.TextView.NumPadKey.Klondike" parent="Widget.TextView.NumPadKey">
+        <item name="android:textSize">12sp</item>
         <item name="android:fontFamily">sans-serif</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">#ffffff</item>
-        <item name="android:paddingTop">6dp</item>
-        <item name="android:paddingBottom">8dp</item>
-        <item name="android:paddingLeft">20dp</item>
-        <item name="android:paddingRight">6dp</item>
-    </style>
-    <style name="Widget.Button.NumPadKey.Sim" >
-        <item name="android:paddingTop">3dp</item>
-        <item name="android:paddingBottom">4dp</item>
-    </style>
-    <style name="TextAppearance.NumPadKey"
-            parent="@android:style/TextAppearance">
-        <item name="android:textSize">34dp</item>
-        <item name="android:fontFamily">sans-serif</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">#ffffff</item>
-    </style>
-    <style name="TextAppearance.NumPadKey.Klondike">
-        <item name="android:textSize">20dp</item>
-        <item name="android:fontFamily">sans-serif-condensed</item>
-        <item name="android:textStyle">normal</item>
         <item name="android:textColor">#80ffffff</item>
+        <item name="android:paddingBottom">0dp</item>
     </style>
 
     <!-- Standard animations for a non-full-screen window or activity. -->
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index aae92e8..c49c318 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -17,12 +17,9 @@
 package com.android.keyguard;
 
 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;
-import android.text.TextWatcher;
 import android.util.AttributeSet;
 import android.view.HapticFeedbackConstants;
 import android.view.KeyEvent;
@@ -38,9 +35,8 @@
  * Base class for PIN and password unlock screens.
  */
 public abstract class KeyguardAbsKeyInputView extends LinearLayout
-        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+        implements KeyguardSecurityView {
     protected KeyguardSecurityCallback mCallback;
-    protected TextView mPasswordEntry;
     protected LockPatternUtils mLockPatternUtils;
     protected SecurityMessageDisplay mSecurityMessageDisplay;
     protected View mEcaView;
@@ -70,9 +66,7 @@
 
     public void reset() {
         // start fresh
-        mPasswordEntry.setText("");
-        mPasswordEntry.requestFocus();
-
+        resetPasswordText(false /* animate */);
         // if the user is currently locked out, enforce it.
         long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
         if (shouldLockout(deadline)) {
@@ -93,34 +87,6 @@
     @Override
     protected void onFinishInflate() {
         mLockPatternUtils = new LockPatternUtils(mContext);
-
-        mPasswordEntry = (TextView) findViewById(getPasswordTextViewId());
-        mPasswordEntry.setOnEditorActionListener(this);
-        mPasswordEntry.addTextChangedListener(this);
-
-        // Set selected property on so the view can send accessibility events.
-        mPasswordEntry.setSelected(true);
-
-        // Poke the wakelock any time the text is selected or modified
-        mPasswordEntry.setOnClickListener(new OnClickListener() {
-            public void onClick(View v) {
-                mCallback.userActivity(0); // TODO: customize timeout for text?
-            }
-        });
-
-        mPasswordEntry.addTextChangedListener(new TextWatcher() {
-            public void onTextChanged(CharSequence s, int start, int before, int count) {
-            }
-
-            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-            }
-
-            public void afterTextChanged(Editable s) {
-                if (mCallback != null) {
-                    mCallback.userActivity(0);
-                }
-            }
-        });
         mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
         mEcaView = findViewById(R.id.keyguard_selector_fade_container);
         View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
@@ -129,12 +95,6 @@
         }
     }
 
-    @Override
-    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
-        // send focus to the password field
-        return mPasswordEntry.requestFocus(direction, previouslyFocusedRect);
-    }
-
     /*
      * Override this if you have a different string for "wrong password"
      *
@@ -145,7 +105,7 @@
     }
 
     protected void verifyPasswordAndUnlock() {
-        String entry = mPasswordEntry.getText().toString();
+        String entry = getPasswordText();
         if (mLockPatternUtils.checkPassword(entry)) {
             mCallback.reportUnlockAttempt(true);
             mCallback.dismiss(true);
@@ -162,12 +122,16 @@
             }
             mSecurityMessageDisplay.setMessage(getWrongPasswordStringId(), true);
         }
-        mPasswordEntry.setText("");
+        resetPasswordText(true /* animate */);
     }
 
+    protected abstract void resetPasswordText(boolean animate);
+    protected abstract String getPasswordText();
+    protected abstract void setPasswordEntryEnabled(boolean enabled);
+
     // Prevent user from using the PIN/Password entry until scheduled deadline.
     protected void handleAttemptLockout(long elapsedRealtimeDeadline) {
-        mPasswordEntry.setEnabled(false);
+        setPasswordEntryEnabled(false);
         long elapsedRealtime = SystemClock.elapsedRealtime();
         new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
 
@@ -193,17 +157,6 @@
     }
 
     @Override
-    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-        // Check if this was the result of hitting the enter key
-        if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE
-                || actionId == EditorInfo.IME_ACTION_NEXT) {
-            verifyPasswordAndUnlock();
-            return true;
-        }
-        return false;
-    }
-
-    @Override
     public boolean needsInput() {
         return false;
     }
@@ -223,21 +176,6 @@
         return mCallback;
     }
 
-    @Override
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-        if (mCallback != null) {
-            mCallback.userActivity(KeyguardConstants.DIGIT_PRESS_WAKE_MILLIS);
-        }
-    }
-
-    @Override
-    public void onTextChanged(CharSequence s, int start, int before, int count) {
-    }
-
-    @Override
-    public void afterTextChanged(Editable s) {
-    }
-
     // Cause a VIRTUAL_KEY vibration
     public void doHapticKeyClick() {
         if (mEnableHaptics) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
index 1f3c176..ec5d040eb 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
@@ -28,8 +28,7 @@
 /**
  * Displays a PIN pad for unlocking.
  */
-public class KeyguardPINView extends KeyguardAbsKeyInputView
-        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+public class KeyguardPINView extends KeyguardPinBasedInputView {
 
     private final AppearAnimationUtils mAppearAnimationUtils;
     private ViewGroup mKeyguardBouncerFrame;
@@ -49,12 +48,12 @@
     }
 
     protected void resetState() {
+        super.resetState();
         if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) {
             mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true);
         } else {
             mSecurityMessageDisplay.setMessage(R.string.kg_pin_instructions, false);
         }
-        mPasswordEntry.setEnabled(true);
     }
 
     @Override
@@ -72,54 +71,6 @@
         mRow2 = (ViewGroup) findViewById(R.id.row2);
         mRow3 = (ViewGroup) findViewById(R.id.row3);
         mDivider = findViewById(R.id.divider);
-        final View ok = findViewById(R.id.key_enter);
-        if (ok != null) {
-            ok.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    doHapticKeyClick();
-                    if (mPasswordEntry.isEnabled()) {
-                        verifyPasswordAndUnlock();
-                    }
-                }
-            });
-            ok.setOnHoverListener(new LiftToActivateListener(getContext()));
-        }
-
-        // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
-        // not a separate view
-        View pinDelete = findViewById(R.id.delete_button);
-        if (pinDelete != null) {
-            pinDelete.setVisibility(View.VISIBLE);
-            pinDelete.setOnClickListener(new OnClickListener() {
-                public void onClick(View v) {
-                    // check for time-based lockouts
-                    if (mPasswordEntry.isEnabled()) {
-                        CharSequence str = mPasswordEntry.getText();
-                        if (str.length() > 0) {
-                            mPasswordEntry.setText(str.subSequence(0, str.length()-1));
-                        }
-                    }
-                    doHapticKeyClick();
-                }
-            });
-            pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
-                public boolean onLongClick(View v) {
-                    // check for time-based lockouts
-                    if (mPasswordEntry.isEnabled()) {
-                        mPasswordEntry.setText("");
-                    }
-                    doHapticKeyClick();
-                    return true;
-                }
-            });
-        }
-
-        mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
-        mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
-                | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
-
-        mPasswordEntry.requestFocus();
     }
 
     @Override
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
index 0c385da..9f820f8 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
@@ -17,15 +17,19 @@
 package com.android.keyguard;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.text.Editable;
 import android.text.InputType;
 import android.text.TextWatcher;
 import android.text.method.TextKeyListener;
 import android.util.AttributeSet;
+import android.view.KeyEvent;
 import android.view.View;
+import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodSubtype;
+import android.widget.TextView;
 import android.widget.TextView.OnEditorActionListener;
 
 import java.util.List;
@@ -40,6 +44,7 @@
     private final boolean mShowImeAtScreenOn;
 
     InputMethodManager mImm;
+    private TextView mPasswordEntry;
 
     public KeyguardPasswordView(Context context) {
         this(context, null);
@@ -82,6 +87,12 @@
     }
 
     @Override
+    public void reset() {
+        super.reset();
+        mPasswordEntry.requestFocus();
+    }
+
+    @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
 
@@ -90,9 +101,12 @@
         mImm = (InputMethodManager) getContext().getSystemService(
                 Context.INPUT_METHOD_SERVICE);
 
+        mPasswordEntry = (TextView) findViewById(getPasswordTextViewId());
         mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
         mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
                 | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+        mPasswordEntry.setOnEditorActionListener(this);
+        mPasswordEntry.addTextChangedListener(this);
 
         // Poke the wakelock any time the text is selected or modified
         mPasswordEntry.setOnClickListener(new OnClickListener() {
@@ -101,6 +115,9 @@
             }
         });
 
+        // Set selected property on so the view can send accessibility events.
+        mPasswordEntry.setSelected(true);
+
         mPasswordEntry.addTextChangedListener(new TextWatcher() {
             public void onTextChanged(CharSequence s, int start, int before, int count) {
             }
@@ -142,6 +159,27 @@
         }
     }
 
+    @Override
+    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+        // send focus to the password field
+        return mPasswordEntry.requestFocus(direction, previouslyFocusedRect);
+    }
+
+    @Override
+    protected void resetPasswordText(boolean animate) {
+        mPasswordEntry.setText("");
+    }
+
+    @Override
+    protected String getPasswordText() {
+        return mPasswordEntry.getText().toString();
+    }
+
+    @Override
+    protected void setPasswordEntryEnabled(boolean enabled) {
+        mPasswordEntry.setEnabled(enabled);
+    }
+
     /**
      * Method adapted from com.android.inputmethod.latin.Utils
      *
@@ -205,4 +243,30 @@
         setAlpha(0);
         animate().alpha(1).withLayer().setDuration(200);
     }
+
+    @Override
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+        if (mCallback != null) {
+            mCallback.userActivity(KeyguardConstants.DIGIT_PRESS_WAKE_MILLIS);
+        }
+    }
+
+    @Override
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+    }
+
+    @Override
+    public void afterTextChanged(Editable s) {
+    }
+
+    @Override
+    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+        // Check if this was the result of hitting the enter key
+        if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE
+                || actionId == EditorInfo.IME_ACTION_NEXT) {
+            verifyPasswordAndUnlock();
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
new file mode 100644
index 0000000..1ef873f
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
+
+/**
+ * A Pin based Keyguard input view
+ */
+public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView
+        implements View.OnKeyListener {
+
+    protected PasswordTextView mPasswordEntry;
+    private View mOkButton;
+    private View mDeleteButton;
+    private View mButton0;
+    private View mButton1;
+    private View mButton2;
+    private View mButton3;
+    private View mButton4;
+    private View mButton5;
+    private View mButton6;
+    private View mButton7;
+    private View mButton8;
+    private View mButton9;
+
+    public KeyguardPinBasedInputView(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardPinBasedInputView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public void reset() {
+        mPasswordEntry.requestFocus();
+        super.reset();
+    }
+
+    @Override
+    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+        // send focus to the password field
+        return mPasswordEntry.requestFocus(direction, previouslyFocusedRect);
+    }
+
+    protected void resetState() {
+        mPasswordEntry.setEnabled(true);
+    }
+
+    @Override
+    protected void setPasswordEntryEnabled(boolean enabled) {
+        mPasswordEntry.setEnabled(enabled);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (KeyEvent.isConfirmKey(keyCode)) {
+            performClick(mOkButton);
+            return true;
+        } else if (keyCode == KeyEvent.KEYCODE_DEL) {
+            performClick(mDeleteButton);
+            return true;
+        }
+        if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
+            int number = keyCode - KeyEvent.KEYCODE_0 ;
+            performNumberClick(number);
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    private void performClick(View view) {
+        view.performClick();
+    }
+
+    private void performNumberClick(int number) {
+        switch (number) {
+            case 0:
+                performClick(mButton0);
+                break;
+            case 1:
+                performClick(mButton1);
+                break;
+            case 2:
+                performClick(mButton2);
+                break;
+            case 3:
+                performClick(mButton3);
+                break;
+            case 4:
+                performClick(mButton4);
+                break;
+            case 5:
+                performClick(mButton5);
+                break;
+            case 6:
+                performClick(mButton6);
+                break;
+            case 7:
+                performClick(mButton7);
+                break;
+            case 8:
+                performClick(mButton8);
+                break;
+            case 9:
+                performClick(mButton9);
+                break;
+        }
+    }
+
+    @Override
+    protected void resetPasswordText(boolean animate) {
+        mPasswordEntry.reset(animate);
+    }
+
+    @Override
+    protected String getPasswordText() {
+        return mPasswordEntry.getText();
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        mPasswordEntry = (PasswordTextView) findViewById(getPasswordTextViewId());
+        mPasswordEntry.setOnKeyListener(this);
+
+        // Set selected property on so the view can send accessibility events.
+        mPasswordEntry.setSelected(true);
+
+        // Poke the wakelock any time the text is selected or modified
+        mPasswordEntry.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                mCallback.userActivity(0); // TODO: customize timeout for text?
+            }
+        });
+
+        mOkButton = findViewById(R.id.key_enter);
+        if (mOkButton != null) {
+            mOkButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    doHapticKeyClick();
+                    if (mPasswordEntry.isEnabled()) {
+                        verifyPasswordAndUnlock();
+                    }
+                }
+            });
+            mOkButton.setOnHoverListener(new LiftToActivateListener(getContext()));
+        }
+
+        mDeleteButton = findViewById(R.id.delete_button);
+        if (mDeleteButton != null) {
+            mDeleteButton.setVisibility(View.VISIBLE);
+            mDeleteButton.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    // check for time-based lockouts
+                    if (mPasswordEntry.isEnabled()) {
+                        mPasswordEntry.deleteLastChar();
+                    }
+                    doHapticKeyClick();
+                }
+            });
+            mDeleteButton.setOnLongClickListener(new View.OnLongClickListener() {
+                public boolean onLongClick(View v) {
+                    // check for time-based lockouts
+                    if (mPasswordEntry.isEnabled()) {
+                        resetPasswordText(true /* animate */);
+                    }
+                    doHapticKeyClick();
+                    return true;
+                }
+            });
+        }
+        mButton0 = findViewById(R.id.key0);
+        mButton1 = findViewById(R.id.key1);
+        mButton2 = findViewById(R.id.key2);
+        mButton3 = findViewById(R.id.key3);
+        mButton4 = findViewById(R.id.key4);
+        mButton5 = findViewById(R.id.key5);
+        mButton6 = findViewById(R.id.key6);
+        mButton7 = findViewById(R.id.key7);
+        mButton8 = findViewById(R.id.key8);
+        mButton9 = findViewById(R.id.key9);
+
+        mPasswordEntry.requestFocus();
+        super.onFinishInflate();
+    }
+
+    @Override
+    public boolean onKey(View v, int keyCode, KeyEvent event) {
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            onKeyDown(keyCode, event);
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
index 09c4e7c..cc90bcb 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
@@ -38,8 +38,7 @@
 /**
  * Displays a PIN pad for unlocking.
  */
-public class KeyguardSimPinView extends KeyguardAbsKeyInputView
-        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+public class KeyguardSimPinView extends KeyguardPinBasedInputView {
     private static final String LOG_TAG = "KeyguardSimPinView";
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
     public static final String TAG = "KeyguardSimPinView";
@@ -58,8 +57,8 @@
     }
 
     public void resetState() {
+        super.resetState();
         mSecurityMessageDisplay.setMessage(R.string.kg_sim_pin_instructions, true);
-        mPasswordEntry.setEnabled(true);
     }
 
     private String getPinPasswordErrorMessage(int attemptsRemaining) {
@@ -94,46 +93,6 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        final View ok = findViewById(R.id.key_enter);
-        if (ok != null) {
-            ok.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    doHapticKeyClick();
-                    verifyPasswordAndUnlock();
-                }
-            });
-        }
-
-        // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
-        // not a separate view
-        View pinDelete = findViewById(R.id.delete_button);
-        if (pinDelete != null) {
-            pinDelete.setVisibility(View.VISIBLE);
-            pinDelete.setOnClickListener(new OnClickListener() {
-                public void onClick(View v) {
-                    CharSequence str = mPasswordEntry.getText();
-                    if (str.length() > 0) {
-                        mPasswordEntry.setText(str.subSequence(0, str.length()-1));
-                    }
-                    doHapticKeyClick();
-                }
-            });
-            pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
-                public boolean onLongClick(View v) {
-                    mPasswordEntry.setText("");
-                    doHapticKeyClick();
-                    return true;
-                }
-            });
-        }
-
-        mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
-        mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
-                | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
-
-        mPasswordEntry.requestFocus();
-
         mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default
         if (mEcaView instanceof EmergencyCarrierArea) {
             ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
@@ -220,12 +179,12 @@
 
     @Override
     protected void verifyPasswordAndUnlock() {
-        String entry = mPasswordEntry.getText().toString();
+        String entry = mPasswordEntry.getText();
 
         if (entry.length() < 4) {
             // otherwise, display a message to the user, and don't submit.
             mSecurityMessageDisplay.setMessage(R.string.kg_invalid_sim_pin_hint, true);
-            mPasswordEntry.setText("");
+            resetPasswordText(true);
             mCallback.userActivity(0);
             return;
         }
@@ -233,7 +192,7 @@
         getSimUnlockProgressDialog().show();
 
         if (mCheckSimPinThread == null) {
-            mCheckSimPinThread = new CheckSimPin(mPasswordEntry.getText().toString()) {
+            mCheckSimPinThread = new CheckSimPin(mPasswordEntry.getText()) {
                 void onSimCheckResponse(final int result, final int attemptsRemaining) {
                     post(new Runnable() {
                         public void run() {
@@ -262,7 +221,7 @@
                                 if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock "
                                         + " CheckSimPin.onSimCheckResponse: " + result
                                         + " attemptsRemaining=" + attemptsRemaining);
-                                mPasswordEntry.setText("");
+                                resetPasswordText(true /* animate */);
                             }
                             mCallback.userActivity(0);
                             mCheckSimPinThread = null;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
index 6215d34..b956e99 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
@@ -39,8 +39,7 @@
 /**
  * Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier.
  */
-public class KeyguardSimPukView extends KeyguardAbsKeyInputView
-        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+public class KeyguardSimPukView extends KeyguardPinBasedInputView {
     private static final String LOG_TAG = "KeyguardSimPukView";
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
     public static final String TAG = "KeyguardSimPukView";
@@ -85,7 +84,7 @@
                     msg = R.string.kg_invalid_confirm_pin_hint;
                 }
             }
-            mPasswordEntry.setText(null);
+            resetPasswordText(true);
             if (msg != 0) {
                 mSecurityMessageDisplay.setMessage(msg, true);
             }
@@ -126,8 +125,8 @@
     }
 
     public void resetState() {
+        super.resetState();
         mStateMachine.reset();
-        mPasswordEntry.setEnabled(true);
     }
 
     @Override
@@ -145,46 +144,6 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        final View ok = findViewById(R.id.key_enter);
-        if (ok != null) {
-            ok.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    doHapticKeyClick();
-                    verifyPasswordAndUnlock();
-                }
-            });
-        }
-
-        // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
-        // not a separate view
-        View pinDelete = findViewById(R.id.delete_button);
-        if (pinDelete != null) {
-            pinDelete.setVisibility(View.VISIBLE);
-            pinDelete.setOnClickListener(new OnClickListener() {
-                public void onClick(View v) {
-                    CharSequence str = mPasswordEntry.getText();
-                    if (str.length() > 0) {
-                        mPasswordEntry.setText(str.subSequence(0, str.length()-1));
-                    }
-                    doHapticKeyClick();
-                }
-            });
-            pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
-                public boolean onLongClick(View v) {
-                    mPasswordEntry.setText("");
-                    doHapticKeyClick();
-                    return true;
-                }
-            });
-        }
-
-        mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
-        mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
-                | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
-
-        mPasswordEntry.requestFocus();
-
         mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default
         if (mEcaView instanceof EmergencyCarrierArea) {
             ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
@@ -276,7 +235,7 @@
     private boolean checkPuk() {
         // make sure the puk is at least 8 digits long.
         if (mPasswordEntry.getText().length() == 8) {
-            mPukText = mPasswordEntry.getText().toString();
+            mPukText = mPasswordEntry.getText();
             return true;
         }
         return false;
@@ -286,14 +245,14 @@
         // make sure the PIN is between 4 and 8 digits
         int length = mPasswordEntry.getText().length();
         if (length >= 4 && length <= 8) {
-            mPinText = mPasswordEntry.getText().toString();
+            mPinText = mPasswordEntry.getText();
             return true;
         }
         return false;
     }
 
     public boolean confirmPin() {
-        return mPinText.equals(mPasswordEntry.getText().toString());
+        return mPinText.equals(mPasswordEntry.getText());
     }
 
     private void updateSim() {
diff --git a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
index 532670f..2d20b02 100644
--- a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
+++ b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
@@ -18,44 +18,54 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.text.SpannableStringBuilder;
-import android.text.style.TextAppearanceSpan;
+import android.graphics.drawable.Drawable;
+import android.os.Debug;
+import android.os.PowerManager;
+import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.view.HapticFeedbackConstants;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.Button;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
 import android.widget.TextView;
 
 import com.android.internal.widget.LockPatternUtils;
 
-public class NumPadKey extends Button {
+public class NumPadKey extends ViewGroup {
     // list of "ABC", etc per digit, starting with '0'
     static String sKlondike[];
 
-    int mDigit = -1;
-    int mTextViewResId;
-    TextView mTextView = null;
-    boolean mEnableHaptics;
+    private int mDigit = -1;
+    private int mTextViewResId;
+    private PasswordTextView mTextView;
+    private TextView mDigitText;
+    private TextView mKlondikeText;
+    private boolean mEnableHaptics;
+    private PowerManager mPM;
 
     private View.OnClickListener mListener = new View.OnClickListener() {
         @Override
         public void onClick(View thisView) {
-            if (mTextView == null) {
-                if (mTextViewResId > 0) {
-                    final View v = NumPadKey.this.getRootView().findViewById(mTextViewResId);
-                    if (v != null && v instanceof TextView) {
-                        mTextView = (TextView) v;
-                    }
+            if (mTextView == null && mTextViewResId > 0) {
+                final View v = NumPadKey.this.getRootView().findViewById(mTextViewResId);
+                if (v != null && v instanceof PasswordTextView) {
+                    mTextView = (PasswordTextView) v;
                 }
             }
-            // check for time-based lockouts
             if (mTextView != null && mTextView.isEnabled()) {
-                mTextView.append(String.valueOf(mDigit));
+                mTextView.append(Character.forDigit(mDigit, 10));
             }
+            userActivity();
             doHapticKeyClick();
         }
     };
 
+    public void userActivity() {
+        mPM.userActivity(SystemClock.uptimeMillis(), false);
+    }
+
     public NumPadKey(Context context) {
         this(context, null);
     }
@@ -66,10 +76,16 @@
 
     public NumPadKey(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+        setFocusable(true);
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumPadKey);
-        mDigit = a.getInt(R.styleable.NumPadKey_digit, mDigit);
-        setTextViewResId(a.getResourceId(R.styleable.NumPadKey_textView, 0));
+
+        try {
+            mDigit = a.getInt(R.styleable.NumPadKey_digit, mDigit);
+            mTextViewResId = a.getResourceId(R.styleable.NumPadKey_textView, 0);
+        } finally {
+            a.recycle();
+        }
 
         setOnClickListener(mListener);
         setOnHoverListener(new LiftToActivateListener(context));
@@ -77,26 +93,32 @@
 
         mEnableHaptics = new LockPatternUtils(context).isTactileFeedbackEnabled();
 
-        SpannableStringBuilder builder = new SpannableStringBuilder();
-        builder.append(String.valueOf(mDigit));
+        mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+        inflater.inflate(R.layout.keyguard_num_pad_key, this, true);
+
+        mDigitText = (TextView) findViewById(R.id.digit_text);
+        mDigitText.setText(Integer.toString(mDigit));
+        mKlondikeText = (TextView) findViewById(R.id.klondike_text);
+
         if (mDigit >= 0) {
             if (sKlondike == null) {
-                sKlondike = context.getResources().getStringArray(
-                        R.array.lockscreen_num_pad_klondike);
+                sKlondike = getResources().getStringArray(R.array.lockscreen_num_pad_klondike);
             }
             if (sKlondike != null && sKlondike.length > mDigit) {
-                final String extra = sKlondike[mDigit];
-                final int extraLen = extra.length();
-                if (extraLen > 0) {
-                    builder.append(" ");
-                    builder.append(extra);
-                    builder.setSpan(
-                        new TextAppearanceSpan(context, R.style.TextAppearance_NumPadKey_Klondike),
-                        builder.length()-extraLen, builder.length(), 0);
+                String klondike = sKlondike[mDigit];
+                final int len = klondike.length();
+                if (len > 0) {
+                    mKlondikeText.setText(klondike);
+                } else {
+                    mKlondikeText.setVisibility(View.INVISIBLE);
                 }
             }
         }
-        setText(builder);
+
+        setBackground(mContext.getDrawable(R.drawable.ripple_drawable));
+        setContentDescription(mDigitText.getText().toString() + mKlondikeText.getText().toString());
     }
 
     @Override
@@ -107,13 +129,27 @@
         ObscureSpeechDelegate.sAnnouncedHeadset = false;
     }
 
-    public void setTextView(TextView tv) {
-        mTextView = tv;
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        measureChildren(widthMeasureSpec, heightMeasureSpec);
     }
 
-    public void setTextViewResId(int resId) {
-        mTextView = null;
-        mTextViewResId = resId;
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        int digitHeight = mDigitText.getMeasuredHeight();
+        int klondikeHeight = mKlondikeText.getMeasuredHeight();
+        int totalHeight = digitHeight + klondikeHeight;
+        int top = getHeight() / 2 - totalHeight / 2;
+        int centerX = getWidth() / 2;
+        int left = centerX - mDigitText.getMeasuredWidth() / 2;
+        int bottom = top + digitHeight;
+        mDigitText.layout(left, top, left + mDigitText.getMeasuredWidth(), bottom);
+        top = (int) (bottom - klondikeHeight * 0.35f);
+        bottom = top + klondikeHeight;
+
+        left = centerX - mKlondikeText.getMeasuredWidth() / 2;
+        mKlondikeText.layout(left, top, left + mKlondikeText.getMeasuredWidth(), bottom);
     }
 
     // Cause a VIRTUAL_KEY vibration
diff --git a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
new file mode 100644
index 0000000..f3ba3a7
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
@@ -0,0 +1,590 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+
+import java.util.ArrayList;
+import java.util.Stack;
+
+/**
+ * A View similar to a textView which contains password text and can animate when the text is
+ * changed
+ */
+public class PasswordTextView extends View {
+
+    private static final float DOT_OVERSHOOT_FACTOR = 1.5f;
+    private static final long DOT_APPEAR_DURATION_OVERSHOOT = 320;
+    private static final long APPEAR_DURATION = 160;
+    private static final long DISAPPEAR_DURATION = 160;
+    private static final long RESET_DELAY_PER_ELEMENT = 40;
+    private static final long RESET_MAX_DELAY = 200;
+
+    /**
+     * The overlap between the text disappearing and the dot appearing animation
+     */
+    private static final long DOT_APPEAR_TEXT_DISAPPEAR_OVERLAP_DURATION = 130;
+
+    /**
+     * The duration the text needs to stay there at least before it can morph into a dot
+     */
+    private static final long TEXT_REST_DURATION_AFTER_APPEAR = 100;
+
+    /**
+     * The duration the text should be visible, starting with the appear animation
+     */
+    private static final long TEXT_VISIBILITY_DURATION = 1300;
+
+    /**
+     * The position in time from [0,1] where the overshoot should be finished and the settle back
+     * animation of the dot should start
+     */
+    private static final float OVERSHOOT_TIME_POSITION = 0.5f;
+
+    /**
+     * The raw text size, will be multiplied by the scaled density when drawn
+     */
+    private final int mTextHeightRaw;
+    private ArrayList<CharState> mTextChars = new ArrayList<>();
+    private String mText = "";
+    private Stack<CharState> mCharPool = new Stack<>();
+    private int mDotSize;
+    private PowerManager mPM;
+    private int mCharPadding;
+    private final Paint mDrawPaint = new Paint();
+    private Interpolator mAppearInterpolator;
+    private Interpolator mDisappearInterpolator;
+    private Interpolator mFastOutSlowInInterpolator;
+    private boolean mShowPassword;
+
+    public PasswordTextView(Context context) {
+        this(context, null);
+    }
+
+    public PasswordTextView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public PasswordTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public PasswordTextView(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        setFocusableInTouchMode(true);
+        setFocusable(true);
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PasswordTextView);
+        try {
+            mTextHeightRaw = a.getInt(R.styleable.PasswordTextView_scaledTextSize, 0);
+        } finally {
+            a.recycle();
+        }
+        mDrawPaint.setFlags(Paint.SUBPIXEL_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
+        mDrawPaint.setTextAlign(Paint.Align.CENTER);
+        mDrawPaint.setColor(0xffffffff);
+        mDrawPaint.setTypeface(Typeface.create("sans-serif-light", 0));
+        mDotSize = getContext().getResources().getDimensionPixelSize(R.dimen.password_dot_size);
+        mCharPadding = getContext().getResources().getDimensionPixelSize(R.dimen
+                .password_char_padding);
+        mShowPassword = Settings.System.getInt(mContext.getContentResolver(),
+                Settings.System.TEXT_SHOW_PASSWORD, 1) == 1;
+        mAppearInterpolator = AnimationUtils.loadInterpolator(mContext,
+                android.R.interpolator.linear_out_slow_in);
+        mDisappearInterpolator = AnimationUtils.loadInterpolator(mContext,
+                android.R.interpolator.fast_out_linear_in);
+        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(mContext,
+                android.R.interpolator.fast_out_slow_in);
+        mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        float totalDrawingWidth = getDrawingWidth();
+        float currentDrawPosition = getWidth() / 2 - totalDrawingWidth / 2;
+        int length = mTextChars.size();
+        Rect bounds = getCharBounds();
+        int charHeight = (bounds.bottom - bounds.top);
+        float yPosition = getHeight() / 2;
+        float charLength = bounds.right - bounds.left;
+        for (int i = 0; i < length; i++) {
+            CharState charState = mTextChars.get(i);
+            float charWidth = charState.draw(canvas, currentDrawPosition, charHeight, yPosition,
+                    charLength);
+            currentDrawPosition += charWidth;
+        }
+    }
+
+    private Rect getCharBounds() {
+        float textHeight = mTextHeightRaw * getResources().getDisplayMetrics().scaledDensity;
+        mDrawPaint.setTextSize(textHeight);
+        Rect bounds = new Rect();
+        mDrawPaint.getTextBounds("0", 0, 1, bounds);
+        return bounds;
+    }
+
+    private float getDrawingWidth() {
+        int width = 0;
+        int length = mTextChars.size();
+        Rect bounds = getCharBounds();
+        int charLength = bounds.right - bounds.left;
+        for (int i = 0; i < length; i++) {
+            CharState charState = mTextChars.get(i);
+            if (i != 0) {
+                width += mCharPadding * charState.currentWidthFactor;
+            }
+            width += charLength * charState.currentWidthFactor;
+        }
+        return width;
+    }
+
+
+    public void append(char c) {
+        int visibleChars = mTextChars.size();
+        mText = mText + c;
+        int newLength = mText.length();
+        CharState charState;
+        if (newLength > visibleChars) {
+            charState = obtainCharState(c);
+            mTextChars.add(charState);
+        } else {
+            charState = mTextChars.get(newLength - 1);
+            charState.whichChar = c;
+        }
+        charState.startAppearAnimation();
+
+        // ensure that the previous element is being swapped
+        if (newLength > 1) {
+            CharState previousState = mTextChars.get(newLength - 2);
+            if (previousState.isDotSwapPending) {
+                previousState.swapToDotWhenAppearFinished();
+            }
+        }
+        userActivity();
+    }
+
+    private void userActivity() {
+        mPM.userActivity(SystemClock.uptimeMillis(), false);
+    }
+
+    public void deleteLastChar() {
+        int length = mText.length();
+        if (length > 0) {
+            mText = mText.substring(0, length - 1);
+            CharState charState = mTextChars.get(length - 1);
+            charState.startRemoveAnimation(0, 0);
+        }
+        userActivity();
+    }
+
+    public String getText() {
+        return mText;
+    }
+
+    private CharState obtainCharState(char c) {
+        CharState charState;
+        if(mCharPool.isEmpty()) {
+            charState = new CharState();
+        } else {
+            charState = mCharPool.pop();
+            charState.reset();
+        }
+        charState.whichChar = c;
+        return charState;
+    }
+
+    public void reset(boolean animated) {
+        mText = "";
+        int length = mTextChars.size();
+        int middleIndex = (length - 1) / 2;
+        long delayPerElement = RESET_DELAY_PER_ELEMENT;
+        for (int i = 0; i < length; i++) {
+            CharState charState = mTextChars.get(i);
+            if (animated) {
+                int delayIndex;
+                if (i <= middleIndex) {
+                    delayIndex = i * 2;
+                } else {
+                    int distToMiddle = i - middleIndex;
+                    delayIndex = (length - 1) - (distToMiddle - 1) * 2;
+                }
+                long startDelay = delayIndex * delayPerElement;
+                startDelay = Math.min(startDelay, RESET_MAX_DELAY);
+                long maxDelay = delayPerElement * (length - 1);
+                maxDelay = Math.min(maxDelay, RESET_MAX_DELAY) + DISAPPEAR_DURATION;
+                charState.startRemoveAnimation(startDelay, maxDelay);
+                charState.removeDotSwapCallbacks();
+            } else {
+                mCharPool.push(charState);
+            }
+        }
+        if (!animated) {
+            mTextChars.clear();
+        }
+    }
+
+    private class CharState {
+        char whichChar;
+        ValueAnimator textAnimator;
+        boolean textAnimationIsGrowing;
+        Animator dotAnimator;
+        boolean dotAnimationIsGrowing;
+        ValueAnimator widthAnimator;
+        boolean widthAnimationIsGrowing;
+        float currentTextSizeFactor;
+        float currentDotSizeFactor;
+        float currentWidthFactor;
+        boolean isDotSwapPending;
+        float currentTextTranslationY = 1.0f;
+        ValueAnimator textTranslateAnimator;
+
+        Animator.AnimatorListener removeEndListener = new AnimatorListenerAdapter() {
+            private boolean mCancelled;
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                mCancelled = true;
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!mCancelled) {
+                    mTextChars.remove(CharState.this);
+                    mCharPool.push(CharState.this);
+                    reset();
+                    cancelAnimator(textTranslateAnimator);
+                    textTranslateAnimator = null;
+                }
+            }
+
+            @Override
+            public void onAnimationStart(Animator animation) {
+                mCancelled = false;
+            }
+        };
+
+        Animator.AnimatorListener dotFinishListener = new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                dotAnimator = null;
+            }
+        };
+
+        Animator.AnimatorListener textFinishListener = new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                textAnimator = null;
+            }
+        };
+
+        Animator.AnimatorListener textTranslateFinishListener = new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                textTranslateAnimator = null;
+            }
+        };
+
+        Animator.AnimatorListener widthFinishListener = new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                widthAnimator = null;
+            }
+        };
+
+        private ValueAnimator.AnimatorUpdateListener dotSizeUpdater
+                = new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                currentDotSizeFactor = (float) animation.getAnimatedValue();
+                invalidate();
+            }
+        };
+
+        private ValueAnimator.AnimatorUpdateListener textSizeUpdater
+                = new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                currentTextSizeFactor = (float) animation.getAnimatedValue();
+                invalidate();
+            }
+        };
+
+        private ValueAnimator.AnimatorUpdateListener textTranslationUpdater
+                = new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                currentTextTranslationY = (float) animation.getAnimatedValue();
+                invalidate();
+            }
+        };
+
+        private ValueAnimator.AnimatorUpdateListener widthUpdater
+                = new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                currentWidthFactor = (float) animation.getAnimatedValue();
+                invalidate();
+            }
+        };
+
+        private Runnable dotSwapperRunnable = new Runnable() {
+            @Override
+            public void run() {
+                performSwap();
+                isDotSwapPending = false;
+            }
+        };
+
+        void reset() {
+            whichChar = 0;
+            currentTextSizeFactor = 0.0f;
+            currentDotSizeFactor = 0.0f;
+            currentWidthFactor = 0.0f;
+            cancelAnimator(textAnimator);
+            textAnimator = null;
+            cancelAnimator(dotAnimator);
+            dotAnimator = null;
+            cancelAnimator(widthAnimator);
+            widthAnimator = null;
+            currentTextTranslationY = 1.0f;
+            removeDotSwapCallbacks();
+        }
+
+        void startRemoveAnimation(long startDelay, long widthDelay) {
+            boolean dotNeedsAnimation = (currentDotSizeFactor > 0.0f && dotAnimator == null)
+                    || (dotAnimator != null && dotAnimationIsGrowing);
+            boolean textNeedsAnimation = (currentTextSizeFactor > 0.0f && textAnimator == null)
+                    || (textAnimator != null && textAnimationIsGrowing);
+            boolean widthNeedsAnimation = (currentWidthFactor > 0.0f && widthAnimator == null)
+                    || (widthAnimator != null && widthAnimationIsGrowing);
+            if (dotNeedsAnimation) {
+                startDotDisappearAnimation(startDelay);
+            }
+            if (textNeedsAnimation) {
+                startTextDisappearAnimation(startDelay);
+            }
+            if (widthNeedsAnimation) {
+                startWidthDisappearAnimation(widthDelay);
+            }
+        }
+
+        void startAppearAnimation() {
+            boolean dotNeedsAnimation = !mShowPassword
+                    && (dotAnimator == null || !dotAnimationIsGrowing);
+            boolean textNeedsAnimation = mShowPassword
+                    && (textAnimator == null || !textAnimationIsGrowing);
+            boolean widthNeedsAnimation = (widthAnimator == null || !widthAnimationIsGrowing);
+            if (dotNeedsAnimation) {
+                startDotAppearAnimation(0);
+            }
+            if (textNeedsAnimation) {
+                startTextAppearAnimation();
+            }
+            if (widthNeedsAnimation) {
+                startWidthAppearAnimation();
+            }
+            if (mShowPassword) {
+                postDotSwap(TEXT_VISIBILITY_DURATION);
+            }
+        }
+
+        /**
+         * Posts a runnable which ensures that the text will be replaced by a dot after {@link
+         * com.android.keyguard.PasswordTextView#TEXT_VISIBILITY_DURATION}.
+         */
+        private void postDotSwap(long delay) {
+            removeDotSwapCallbacks();
+            postDelayed(dotSwapperRunnable, delay);
+            isDotSwapPending = true;
+        }
+
+        private void removeDotSwapCallbacks() {
+            removeCallbacks(dotSwapperRunnable);
+            isDotSwapPending = false;
+        }
+
+        void swapToDotWhenAppearFinished() {
+            removeDotSwapCallbacks();
+            if (textAnimator != null) {
+                long remainingDuration = textAnimator.getDuration()
+                        - textAnimator.getCurrentPlayTime();
+                postDotSwap(remainingDuration + TEXT_REST_DURATION_AFTER_APPEAR);
+            } else {
+                performSwap();
+            }
+        }
+
+        private void performSwap() {
+            startTextDisappearAnimation(0);
+            startDotAppearAnimation(DISAPPEAR_DURATION
+                    - DOT_APPEAR_TEXT_DISAPPEAR_OVERLAP_DURATION);
+        }
+
+        private void startWidthDisappearAnimation(long widthDelay) {
+            cancelAnimator(widthAnimator);
+            widthAnimator = ValueAnimator.ofFloat(currentWidthFactor, 0.0f);
+            widthAnimator.addUpdateListener(widthUpdater);
+            widthAnimator.addListener(widthFinishListener);
+            widthAnimator.addListener(removeEndListener);
+            widthAnimator.setDuration((long) (DISAPPEAR_DURATION * currentWidthFactor));
+            widthAnimator.setStartDelay(widthDelay);
+            widthAnimator.start();
+            widthAnimationIsGrowing = false;
+        }
+
+        private void startTextDisappearAnimation(long startDelay) {
+            cancelAnimator(textAnimator);
+            textAnimator = ValueAnimator.ofFloat(currentTextSizeFactor, 0.0f);
+            textAnimator.addUpdateListener(textSizeUpdater);
+            textAnimator.addListener(textFinishListener);
+            textAnimator.setInterpolator(mDisappearInterpolator);
+            textAnimator.setDuration((long) (DISAPPEAR_DURATION * currentTextSizeFactor));
+            textAnimator.setStartDelay(startDelay);
+            textAnimator.start();
+            textAnimationIsGrowing = false;
+        }
+
+        private void startDotDisappearAnimation(long startDelay) {
+            cancelAnimator(dotAnimator);
+            ValueAnimator animator = ValueAnimator.ofFloat(currentDotSizeFactor, 0.0f);
+            animator.addUpdateListener(dotSizeUpdater);
+            animator.addListener(dotFinishListener);
+            animator.setInterpolator(mDisappearInterpolator);
+            long duration = (long) (DISAPPEAR_DURATION * Math.min(currentDotSizeFactor, 1.0f));
+            animator.setDuration(duration);
+            animator.setStartDelay(startDelay);
+            animator.start();
+            dotAnimator = animator;
+            dotAnimationIsGrowing = false;
+        }
+
+        private void startWidthAppearAnimation() {
+            cancelAnimator(widthAnimator);
+            widthAnimator = ValueAnimator.ofFloat(currentWidthFactor, 1.0f);
+            widthAnimator.addUpdateListener(widthUpdater);
+            widthAnimator.addListener(widthFinishListener);
+            widthAnimator.setDuration((long) (APPEAR_DURATION * (1f - currentWidthFactor)));
+            widthAnimator.start();
+            widthAnimationIsGrowing = true;
+        }
+
+        private void startTextAppearAnimation() {
+            cancelAnimator(textAnimator);
+            textAnimator = ValueAnimator.ofFloat(currentTextSizeFactor, 1.0f);
+            textAnimator.addUpdateListener(textSizeUpdater);
+            textAnimator.addListener(textFinishListener);
+            textAnimator.setInterpolator(mAppearInterpolator);
+            textAnimator.setDuration((long) (APPEAR_DURATION * (1f - currentTextSizeFactor)));
+            textAnimator.start();
+            textAnimationIsGrowing = true;
+
+            // handle translation
+            if (textTranslateAnimator == null) {
+                textTranslateAnimator = ValueAnimator.ofFloat(1.0f, 0.0f);
+                textTranslateAnimator.addUpdateListener(textTranslationUpdater);
+                textTranslateAnimator.addListener(textTranslateFinishListener);
+                textTranslateAnimator.setInterpolator(mAppearInterpolator);
+                textTranslateAnimator.setDuration(APPEAR_DURATION);
+                textTranslateAnimator.start();
+            }
+        }
+
+        private void startDotAppearAnimation(long delay) {
+            cancelAnimator(dotAnimator);
+            if (!mShowPassword) {
+                // We perform an overshoot animation
+                ValueAnimator overShootAnimator = ValueAnimator.ofFloat(currentDotSizeFactor,
+                        DOT_OVERSHOOT_FACTOR);
+                overShootAnimator.addUpdateListener(dotSizeUpdater);
+                overShootAnimator.setInterpolator(mAppearInterpolator);
+                long overShootDuration = (long) (DOT_APPEAR_DURATION_OVERSHOOT
+                        * OVERSHOOT_TIME_POSITION);
+                overShootAnimator.setDuration(overShootDuration);
+                ValueAnimator settleBackAnimator = ValueAnimator.ofFloat(DOT_OVERSHOOT_FACTOR,
+                        1.0f);
+                settleBackAnimator.addUpdateListener(dotSizeUpdater);
+                settleBackAnimator.setDuration(DOT_APPEAR_DURATION_OVERSHOOT - overShootDuration);
+                settleBackAnimator.addListener(dotFinishListener);
+                AnimatorSet animatorSet = new AnimatorSet();
+                animatorSet.playSequentially(overShootAnimator, settleBackAnimator);
+                animatorSet.setStartDelay(delay);
+                animatorSet.start();
+                dotAnimator = animatorSet;
+            } else {
+                ValueAnimator growAnimator = ValueAnimator.ofFloat(currentDotSizeFactor, 1.0f);
+                growAnimator.addUpdateListener(dotSizeUpdater);
+                growAnimator.setDuration((long) (APPEAR_DURATION * (1.0f - currentDotSizeFactor)));
+                growAnimator.addListener(dotFinishListener);
+                growAnimator.setStartDelay(delay);
+                growAnimator.start();
+                dotAnimator = growAnimator;
+            }
+            dotAnimationIsGrowing = true;
+        }
+
+        private void cancelAnimator(Animator animator) {
+            if (animator != null) {
+                animator.cancel();
+            }
+        }
+
+        /**
+         * Draw this char to the canvas.
+         *
+         * @return The width this character contributes, including padding.
+         */
+        public float draw(Canvas canvas, float currentDrawPosition, int charHeight, float yPosition,
+                float charLength) {
+            boolean textVisible = currentTextSizeFactor > 0;
+            boolean dotVisible = currentDotSizeFactor > 0;
+            float charWidth = charLength * currentWidthFactor;
+            if (textVisible) {
+                float currYPosition = yPosition + charHeight / 2.0f * currentTextSizeFactor
+                        + charHeight * currentTextTranslationY * 0.8f;
+                canvas.save();
+                float centerX = currentDrawPosition + charWidth / 2;
+                canvas.translate(centerX, currYPosition);
+                canvas.scale(currentTextSizeFactor, currentTextSizeFactor);
+                canvas.drawText(Character.toString(whichChar), 0, 0, mDrawPaint);
+                canvas.restore();
+            }
+            if (dotVisible) {
+                canvas.save();
+                float centerX = currentDrawPosition + charWidth / 2;
+                canvas.translate(centerX, yPosition);
+                canvas.drawCircle(0, 0, mDotSize / 2 * currentDotSizeFactor, mDrawPaint);
+                canvas.restore();
+            }
+            return charWidth + mCharPadding * currentWidthFactor;
+        }
+    }
+}