summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSelim Cinek <cinek@google.com>2014-06-20 16:37:04 -0700
committerSelim Cinek <cinek@google.com>2014-06-30 18:48:41 +0000
commit4e8b9ed30b67e5449d987e674b2966dc7f3ac224 (patch)
tree7294d84b5c57aca74731b95b6888095bdd55845f
parent5f834774c77b290e951c712608d1dde2251cd0a5 (diff)
downloadframeworks_base-4e8b9ed30b67e5449d987e674b2966dc7f3ac224.zip
frameworks_base-4e8b9ed30b67e5449d987e674b2966dc7f3ac224.tar.gz
frameworks_base-4e8b9ed30b67e5449d987e674b2966dc7f3ac224.tar.bz2
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
-rw-r--r--core/res/res/values/attrs.xml5
-rw-r--r--core/res/res/values/styles.xml27
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_done_wht.pngbin0 -> 1374 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_input_delete.pngbin1031 -> 0 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_done_wht.pngbin0 -> 1206 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_input_delete.pngbin786 -> 0 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_done_wht.pngbin0 -> 1600 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_input_delete.pngbin1307 -> 0 bytes
-rw-r--r--packages/Keyguard/res/drawable-xxhdpi/ic_done_wht.pngbin0 -> 1133 bytes
-rw-r--r--packages/Keyguard/res/drawable-xxxhdpi/ic_done_wht.pngbin0 -> 2753 bytes
-rw-r--r--packages/Keyguard/res/drawable/ic_backspace_24dp.xml28
-rw-r--r--packages/Keyguard/res/drawable/ripple_drawable.xml (renamed from packages/SystemUI/res/drawable/ripple_drawable.xml)0
-rw-r--r--packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml49
-rw-r--r--packages/Keyguard/res/layout/keyguard_bouncer.xml3
-rw-r--r--packages/Keyguard/res/layout/keyguard_num_pad_key.xml31
-rw-r--r--packages/Keyguard/res/layout/keyguard_pin_view.xml397
-rw-r--r--packages/Keyguard/res/layout/keyguard_sim_pin_view.xml392
-rw-r--r--packages/Keyguard/res/layout/keyguard_sim_puk_view.xml391
-rw-r--r--packages/Keyguard/res/layout/keyguard_simple_host_view.xml (renamed from packages/Keyguard/res/layout-port/keyguard_simple_host_view.xml)3
-rw-r--r--packages/Keyguard/res/values/arrays.xml2
-rw-r--r--packages/Keyguard/res/values/attrs.xml4
-rw-r--r--packages/Keyguard/res/values/dimens.xml9
-rw-r--r--packages/Keyguard/res/values/styles.xml36
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java80
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java53
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java64
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java215
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java53
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java53
-rw-r--r--packages/Keyguard/src/com/android/keyguard/NumPadKey.java108
-rw-r--r--packages/Keyguard/src/com/android/keyguard/PasswordTextView.java590
32 files changed, 1626 insertions, 970 deletions
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 @@ please see styles_device_defaults.xml.
<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
index af7941f..af7941f 100644
--- a/packages/SystemUI/res/drawable/ripple_drawable.xml
+++ b/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..72591d4
--- /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
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: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>
+ <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="TextAppearance.NumPadKey"
- parent="@android:style/TextAppearance">
- <item name="android:textSize">34dp</item>
+ <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>
- </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 @@ import com.android.internal.widget.LockPatternUtils;
* 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 abstract class KeyguardAbsKeyInputView extends LinearLayout
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 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
@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 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
}
}
- @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 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
}
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 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
}
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 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
}
@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 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
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 @@ import android.widget.TextView.OnEditorActionListener;
/**
* 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 @@ public class KeyguardPINView extends KeyguardAbsKeyInputView
}
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 @@ public class KeyguardPINView extends KeyguardAbsKeyInputView
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 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
private final boolean mShowImeAtScreenOn;
InputMethodManager mImm;
+ private TextView mPasswordEntry;
public KeyguardPasswordView(Context context) {
this(context, null);
@@ -82,6 +87,12 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
}
@Override
+ public void reset() {
+ super.reset();
+ mPasswordEntry.requestFocus();
+ }
+
+ @Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -90,9 +101,12 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
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 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
}
});
+ // 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 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
}
}
+ @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 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
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 @@ import android.widget.TextView.OnEditorActionListener;
/**
* 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 class KeyguardSimPinView extends KeyguardAbsKeyInputView
}
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 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView
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 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView
@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 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView
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 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView
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 @@ import com.android.internal.telephony.PhoneConstants;
/**
* 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 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView
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 class KeyguardSimPukView extends KeyguardAbsKeyInputView
}
public void resetState() {
+ super.resetState();
mStateMachine.reset();
- mPasswordEntry.setEnabled(true);
}
@Override
@@ -145,46 +144,6 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView
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 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView
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 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView
// 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 @@ package com.android.keyguard;
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 class NumPadKey extends Button {
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 @@ public class NumPadKey extends Button {
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 @@ public class NumPadKey extends Button {
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;
+ }
+ }
+}