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
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
BIN
packages/Keyguard/res/drawable-hdpi/ic_done_wht.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
BIN
packages/Keyguard/res/drawable-mdpi/ic_done_wht.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 786 B |
BIN
packages/Keyguard/res/drawable-xhdpi/ic_done_wht.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
BIN
packages/Keyguard/res/drawable-xxhdpi/ic_done_wht.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
packages/Keyguard/res/drawable-xxxhdpi/ic_done_wht.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
28
packages/Keyguard/res/drawable/ic_backspace_24dp.xml
Normal file
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
31
packages/Keyguard/res/layout/keyguard_num_pad_key.xml
Normal file
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -19,36 +19,20 @@
|
||||
|
||||
<resources>
|
||||
<!-- Keyguard PIN pad styles -->
|
||||
<style name="Widget.Button.NumPadKey"
|
||||
parent="@android:style/Widget.Button">
|
||||
<style name="Widget.TextView.NumPadKey" parent="@android:style/Widget.TextView">
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:gravity">left|center_vertical</item>
|
||||
<item name="android:background">?android:attr/selectableItemBackground</item>
|
||||
<item name="android:textSize">34dp</item>
|
||||
<item name="android:gravity">center_horizontal|center_vertical</item>
|
||||
<item name="android:background">@null</item>
|
||||
<item name="android:textSize">36sp</item>
|
||||
<item name="android:fontFamily">sans-serif-light</item>
|
||||
<item name="android:textColor">#ffffffff</item>
|
||||
<item name="android:paddingBottom">-16dp</item>
|
||||
</style>
|
||||
<style name="Widget.TextView.NumPadKey.Klondike" parent="Widget.TextView.NumPadKey">
|
||||
<item name="android:textSize">12sp</item>
|
||||
<item name="android:fontFamily">sans-serif</item>
|
||||
<item name="android:textStyle">normal</item>
|
||||
<item name="android:textColor">#ffffff</item>
|
||||
<item name="android:paddingTop">6dp</item>
|
||||
<item name="android:paddingBottom">8dp</item>
|
||||
<item name="android:paddingLeft">20dp</item>
|
||||
<item name="android:paddingRight">6dp</item>
|
||||
</style>
|
||||
<style name="Widget.Button.NumPadKey.Sim" >
|
||||
<item name="android:paddingTop">3dp</item>
|
||||
<item name="android:paddingBottom">4dp</item>
|
||||
</style>
|
||||
<style name="TextAppearance.NumPadKey"
|
||||
parent="@android:style/TextAppearance">
|
||||
<item name="android:textSize">34dp</item>
|
||||
<item name="android:fontFamily">sans-serif</item>
|
||||
<item name="android:textStyle">normal</item>
|
||||
<item name="android:textColor">#ffffff</item>
|
||||
</style>
|
||||
<style name="TextAppearance.NumPadKey.Klondike">
|
||||
<item name="android:textSize">20dp</item>
|
||||
<item name="android:fontFamily">sans-serif-condensed</item>
|
||||
<item name="android:textStyle">normal</item>
|
||||
<item name="android:textColor">#80ffffff</item>
|
||||
<item name="android:paddingBottom">0dp</item>
|
||||
</style>
|
||||
|
||||
<!-- Standard animations for a non-full-screen window or activity. -->
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -192,17 +156,6 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
|
||||
return false;
|
||||
}
|
||||
|
||||
@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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
@@ -81,6 +86,12 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
|
||||
mImm.hideSoftInputFromWindow(getWindowToken(), 0);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
590
packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||