Add fingerprint settings.
- Improved layout. - Enrollment is now working. - Added vibration and progress feedback. - Better fingerprint animation logic. - Poke userActivity() when sensor is touched. - Added progress animation. - Only show fingerprint menu item on devices that have fingerprint hw - Set View state to GONE for views that aren't shown & fix resulting layout issue - Fix bug where stage wasn't advancing when returning from ChooseLockGeneric. - Renamed FingerprintSettings to FingerprintEnroll - Fixed bug with storing fingerprint ids that prevented the last one from being removed. - Added better progress indication. When remaining is at max, count that as the first step. - Fix whitespace formatting in CL Fixes bug 1953439 Change-Id: I721bf440c63640203af94ce21340d8281076c249
@@ -72,6 +72,8 @@
|
||||
<uses-permission android:name="android.permission.READ_SEARCH_INDEXABLES" />
|
||||
<uses-permission android:name="android.permission.OEM_UNLOCK_STATE" />
|
||||
<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.MANAGE_FINGERPRINT" />
|
||||
|
||||
<application android:label="@string/settings_label"
|
||||
android:icon="@mipmap/ic_launcher_settings"
|
||||
@@ -1219,6 +1221,9 @@
|
||||
<activity android:name="ConfirmLockPassword"
|
||||
android:windowSoftInputMode="stateVisible|adjustResize"/>
|
||||
|
||||
<activity android:name="FingerprintSettings" android:exported="false"/>
|
||||
<activity android:name="FingerprintEnroll" android:exported="false"/>
|
||||
|
||||
<!-- Note this must not be exported since it returns the password in the intent -->
|
||||
<activity android:name="ConfirmLockPattern$InternalActivity"
|
||||
android:exported="false"/>
|
||||
|
BIN
res/drawable-nodpi/fingerprint_anim00.png
Normal file
After Width: | Height: | Size: 928 B |
BIN
res/drawable-nodpi/fingerprint_anim01.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
res/drawable-nodpi/fingerprint_anim02.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
res/drawable-nodpi/fingerprint_anim03.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
res/drawable-nodpi/fingerprint_anim04.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
res/drawable-nodpi/fingerprint_anim05.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
res/drawable-nodpi/fingerprint_anim06.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
res/drawable-nodpi/fingerprint_anim07.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
res/drawable-nodpi/fingerprint_anim08.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
res/drawable-nodpi/fingerprint_anim09.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
BIN
res/drawable-nodpi/fingerprint_anim10.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
res/drawable-nodpi/fingerprint_anim11.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
res/drawable-nodpi/fingerprint_anim12.png
Normal file
After Width: | Height: | Size: 928 B |
BIN
res/drawable-nodpi/fingerprint_in_app_indicator.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
res/drawable-nodpi/fingerprint_sensor_location.png
Normal file
After Width: | Height: | Size: 15 KiB |
35
res/drawable/fingerprint_animation.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 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.
|
||||
-->
|
||||
|
||||
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/fingerprint_animation"
|
||||
android:oneshot="false"
|
||||
android:duration="1000">
|
||||
<item android:drawable="@drawable/fingerprint_anim00" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim01" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim02" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim03" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim04" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim05" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim06" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim07" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim08" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim09" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim10" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim11" android:duration="77" />
|
||||
<item android:drawable="@drawable/fingerprint_anim12" android:duration="77" />
|
||||
</animation-list>
|
30
res/drawable/fingerprint_progress_ring.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2015 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.
|
||||
-->
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape
|
||||
android:innerRadius="96dip"
|
||||
android:shape="ring"
|
||||
android:thickness="4dip">
|
||||
<gradient
|
||||
android:startColor="@color/fingerprint_progress_ring_color"
|
||||
android:endColor="@color/fingerprint_progress_ring_color"
|
||||
android:angle="180"
|
||||
/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
22
res/drawable/fingerprint_progress_ring_bg.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2015 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.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:innerRadius="96dip"
|
||||
android:shape="ring"
|
||||
android:thickness="4dip"
|
||||
android:color="@color/fingerprint_progress_ring_bg">
|
||||
</shape>
|
143
res/layout-land/fingerprint_enroll.xml
Normal file
@@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2015 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.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<!-- Left area -->
|
||||
<LinearLayout
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="0.4"
|
||||
android:background="@color/fingerprint_title_area_bg"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fingerprint_enroll_title"
|
||||
android:background="@color/fingerprint_title_area_bg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="20dip"
|
||||
android:layout_marginStart="40dip"
|
||||
android:layout_marginEnd="40dip"
|
||||
style="@style/TextAppearance.FingerprintTitle"
|
||||
android:layout_alignParentBottom="true"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fingerprint_enroll_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="0.6"
|
||||
android:layout_marginTop="24dip"
|
||||
android:layout_marginStart="40dip"
|
||||
android:layout_marginEnd="40dip"
|
||||
android:layout_marginBottom="36dip"
|
||||
style="@style/TextAppearance.FingerprintMessage"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Right area -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/fingerprint_view_selector"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dip"
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/fingerprint_progress_ring_bg">
|
||||
|
||||
<!-- One of the following views will show for any given mode -->
|
||||
<ProgressBar
|
||||
android:id="@+id/fingerprint_progress_bar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="200dip"
|
||||
android:layout_height="200dip"
|
||||
android:max="100"
|
||||
android:progress="0"
|
||||
android:indeterminate="false"
|
||||
android:progressDrawable="@drawable/fingerprint_progress_ring" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprint_sensor_location"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/fingerprint_sensor_location"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprint_animator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/fingerprint_animation"
|
||||
android:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprint_in_app_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/fingerprint_in_app_indicator"
|
||||
android:visibility="visible" />
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Button area -->
|
||||
<LinearLayout
|
||||
android:id="@+id/fingerprint_enroll_button_area"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/fingerprint_enroll_button_add"
|
||||
style="@style/SecurityPreferenceButton"
|
||||
android:text="@string/fingerprint_enroll_button_add" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/fingerprint_enroll_button_next"
|
||||
style="@style/SecurityPreferenceButton"
|
||||
android:text="@string/fingerprint_enroll_button_next" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
128
res/layout/fingerprint_enroll.xml
Normal file
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2015 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.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal">
|
||||
|
||||
<!-- Upper title area -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="0.3"
|
||||
android:background="@color/fingerprint_title_area_bg">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fingerprint_enroll_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="20dip"
|
||||
android:layout_marginStart="40dip"
|
||||
android:layout_marginEnd="40dip"
|
||||
style="@style/TextAppearance.FingerprintTitle"
|
||||
android:layout_alignParentBottom="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- Lower message area -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="0.6"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fingerprint_enroll_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dip"
|
||||
android:layout_marginStart="40dip"
|
||||
android:layout_marginEnd="40dip"
|
||||
android:layout_marginBottom="36dip"
|
||||
style="@style/TextAppearance.FingerprintMessage"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fingerprint_view_selector"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/fingerprint_progress_ring_bg">
|
||||
|
||||
<!-- One of the following views will show for any given mode -->
|
||||
<ProgressBar
|
||||
android:id="@+id/fingerprint_progress_bar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="200dip"
|
||||
android:layout_height="200dip"
|
||||
android:max="100"
|
||||
android:progress="0"
|
||||
android:indeterminate="false"
|
||||
android:progressDrawable="@drawable/fingerprint_progress_ring" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprint_sensor_location"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/fingerprint_sensor_location" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprint_animator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/fingerprint_animation" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprint_in_app_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/fingerprint_in_app_indicator" />
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Button area -->
|
||||
<LinearLayout
|
||||
android:id="@+id/fingerprint_enroll_button_area"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/fingerprint_enroll_button_add"
|
||||
style="@style/SecurityPreferenceButton"
|
||||
android:text="@string/fingerprint_enroll_button_add" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/fingerprint_enroll_button_next"
|
||||
style="@style/SecurityPreferenceButton"
|
||||
android:text="@string/fingerprint_enroll_button_next" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@@ -60,6 +60,12 @@
|
||||
<color name="unlock_pattern_view_success_color">@color/theme_accent</color>
|
||||
<color name="unlock_pattern_view_error_color">#fff4511e</color>
|
||||
|
||||
<color name="fingerprint_title_area_bg">#ff009688</color>
|
||||
<color name="fingerprint_title_color">#ffffffff</color>
|
||||
<color name="fingerprint_message_color">#de000000</color>
|
||||
<color name="fingerprint_progress_ring_color">#ff009688</color>
|
||||
<color name="fingerprint_progress_ring_bg">#20000000</color>
|
||||
|
||||
<color name="running_processes_system_ram">#ff384248</color>
|
||||
<color name="running_processes_apps_ram">#ff009587</color>
|
||||
<color name="running_processes_free_ram">#ffced7db</color>
|
||||
|
@@ -756,6 +756,54 @@
|
||||
<!-- In the security screen, the header title for settings related to Passwords-->
|
||||
<string name="security_passwords_title">Passwords</string>
|
||||
|
||||
<!-- Fingerprint enrollment and settings --><skip />
|
||||
<!-- Title shown for menu item that launches fingerprint settings or enrollment [CHAR LIMIT=22] -->
|
||||
<string name="security_settings_fingerprint_preference_title">Fingerprint</string>
|
||||
<!-- Message shown for menu item that launches fingerprint settings or enrollment -->
|
||||
<plurals name="security_settings_fingerprint_preference_summary">
|
||||
<item quantity="one"><xliff:g id="count">%1$d</xliff:g> fingerprint enrolled</item>
|
||||
<item quantity="other"><xliff:g id="count">%1$d</xliff:g> fingerprints enrolled</item>
|
||||
</plurals>
|
||||
<!-- Introduction title shown in fingerprint enrollment dialog [CHAR LIMIT=22] -->
|
||||
<string name="security_settings_fingerprint_enroll_onboard_title">Fingerprint setup</string>
|
||||
<!-- Introduction detail message shown in fingerprint enrollment dialog -->
|
||||
<string name="security_settings_fingerprint_enroll_onboard_message">
|
||||
To use your fingerprint to unlock your screen or confirm purchases, we\'ll need to:
|
||||
\n\u2713 Set up your background screen lock method
|
||||
\n\u2713 Add your fingerprint</string>
|
||||
<!-- Title shown in fingerprint enrollment dialog to begin enrollment [CHAR LIMIT=22]-->
|
||||
<string name="security_settings_fingerprint_enroll_start_title">Let\'s start!</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog to begin enrollment -->
|
||||
<string name="security_settings_fingerprint_enroll_start_message">Put your finger on the fingerprint sensor. Lift after you feel a vibration.</string>
|
||||
<!-- Title shown in fingerprint enrollment dialog to repeat touching the fingerprint sensor [CHAR LIMIT=22] -->
|
||||
<string name="security_settings_fingerprint_enroll_repeat_title">Great! Now repeat.</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog to repeat touching the fingerprint sensor -->
|
||||
<string name="security_settings_fingerprint_enroll_repeat_message">Put the same finger on the fingerprint sensor and lift after you feel a vibration.</string>
|
||||
<!-- Title shown in fingerprint enrollment dialog once enrollment is completed [CHAR LIMIT=22] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_title">Fingerprint added!</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_message">Whenever you see this icon, you can use your fingerprint for identification or to authorize a purchase.</string>
|
||||
<!-- Button text shown at the end of enrollment that allows the user to add another fingerprint -->
|
||||
<string name="fingerprint_enroll_button_add">Add</string>
|
||||
<!-- Button text shown at the end of enrollment that allows the user to move to the next step -->
|
||||
<string name="fingerprint_enroll_button_next">Next</string>
|
||||
<!-- Error message shown when the fingerprint cannot be recognized -->
|
||||
<string name="fingerprint_acquired_try_again">Partial fingerprint detected. Please try again.</string>
|
||||
<!-- Error message shown when the fingerprint sensor needs cleaning -->
|
||||
<string name="fingerprint_acquired_imager_dirty">Fingerprint sensor is dirty. Please clean and try again.</string>
|
||||
<!-- Error message shown when the user removes their finger from the sensor too quickly -->
|
||||
<string name="fingerprint_acquired_too_fast">Finger moved to fast. Please try again.</string>
|
||||
<!-- Error message shown when the user moves their finger too slowly -->
|
||||
<string name="fingerprint_acquired_too_slow">Finger moved to slow. Please try again.</string>
|
||||
<!-- Generic error message shown when the fingerprint hardware can't recognize the fingerprint -->
|
||||
<string name="fingerprint_error_unable_to_process">Unable to process. Try again.</string>
|
||||
<!-- Error message shown when the fingerprint hardware can't be accessed -->
|
||||
<string name="fingerprint_error_hw_not_available">Hardware not available.</string>
|
||||
<!-- Error message shown when the fingerprint hardware has run out of room for storing fingerprints -->
|
||||
<string name="fingerprint_error_no_space">Fingerprint can\'t be stored. Please remove an existing fingerprint.</string>
|
||||
<!-- Error message shown when the fingerprint hardware timer has expired and the user needs to restart the operation. -->
|
||||
<string name="fingerprint_error_timeout">Fingerprint time out reached. Try again.</string>
|
||||
|
||||
<!-- Title of the preferences category for preference items to control encryption -->
|
||||
<string name="crypt_keeper_settings_title">Encryption</string>
|
||||
|
||||
|
@@ -351,4 +351,19 @@
|
||||
|
||||
<style name="TextAppearance.ResultTitle" parent="TextAppearance.CategoryTitle">
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.FingerprintTitle"
|
||||
parent="android:TextAppearance.Material.Large.Inverse">
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:textSize">24sp</item>
|
||||
<item name="android:textColor">@color/fingerprint_title_color</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.FingerprintMessage"
|
||||
parent="android:TextAppearance.Material.Medium.Inverse">
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:textColor">@color/fingerprint_message_color</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
435
src/com/android/settings/FingerprintEnroll.java
Normal file
@@ -0,0 +1,435 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.settings;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.Animator.AnimatorListener;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.media.AudioAttributes;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.Vibrator;
|
||||
import android.service.fingerprint.FingerprintManager;
|
||||
import android.service.fingerprint.FingerprintManagerReceiver;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
|
||||
/**
|
||||
* Wizard to enroll a fingerprint
|
||||
*/
|
||||
public class FingerprintEnroll extends SettingsActivity {
|
||||
/**
|
||||
* Used by the choose fingerprint wizard to indicate the wizard is
|
||||
* finished, and each activity in the wizard should finish.
|
||||
* <p>
|
||||
* Previously, each activity in the wizard would finish itself after
|
||||
* starting the next activity. However, this leads to broken 'Back'
|
||||
* behavior. So, now an activity does not finish itself until it gets this
|
||||
* result.
|
||||
*/
|
||||
static final int RESULT_FINISHED = RESULT_FIRST_USER;
|
||||
|
||||
@Override
|
||||
public Intent getIntent() {
|
||||
Intent modIntent = new Intent(super.getIntent());
|
||||
modIntent.putExtra(EXTRA_SHOW_FRAGMENT, FingerprintEnrollFragment.class.getName());
|
||||
return modIntent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isValidFragment(String fragmentName) {
|
||||
if (FingerprintEnrollFragment.class.getName().equals(fragmentName)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
super.onCreate(savedInstanceState);
|
||||
CharSequence msg = getText(R.string.security_settings_fingerprint_preference_title);
|
||||
setTitle(msg);
|
||||
}
|
||||
|
||||
public static class FingerprintEnrollFragment extends Fragment implements View.OnClickListener {
|
||||
private static final String TAG = "FingerprintEnroll";
|
||||
private static final boolean DEBUG = true;
|
||||
private static final int CONFIRM_REQUEST = 101;
|
||||
private static final int CHOOSE_LOCK_GENERIC_REQUEST = 102;
|
||||
private static final long ENROLL_TIMEOUT = 300*1000;
|
||||
|
||||
private PowerManager mPowerManager;
|
||||
private FingerprintManager mFingerprintManager;
|
||||
private View mContentView;
|
||||
private TextView mTitleText;
|
||||
private TextView mMessageText;
|
||||
private Stage mStage;
|
||||
private int mEnrollmentSteps;
|
||||
private boolean mEnrolling;
|
||||
private Vibrator mVibrator;
|
||||
private ProgressBar mProgressBar;
|
||||
private ImageView mFingerprintAnimator;
|
||||
private ObjectAnimator mProgressAnim;
|
||||
private final AnimatorListener mProgressAnimationListener = new AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) { }
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) { }
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mProgressBar.getProgress() >= 100) {
|
||||
updateStage(Stage.EnrollingFinish);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) { }
|
||||
};
|
||||
|
||||
// This contains a list of all views managed by the UI. Used to determine which views
|
||||
// need to be shown/hidden at each stage. It should be the union of the lists that follow
|
||||
private static final int MANAGED_VIEWS[] = {
|
||||
R.id.fingerprint_sensor_location,
|
||||
R.id.fingerprint_animator,
|
||||
R.id.fingerprint_enroll_button_area,
|
||||
R.id.fingerprint_in_app_indicator,
|
||||
R.id.fingerprint_enroll_button_add,
|
||||
R.id.fingerprint_enroll_button_next,
|
||||
R.id.fingerprint_progress_bar
|
||||
};
|
||||
|
||||
private static final int VIEWS_ENROLL_ONBOARD[] = {
|
||||
R.id.fingerprint_enroll_button_area,
|
||||
R.id.fingerprint_enroll_button_next
|
||||
};
|
||||
|
||||
private static final int VIEWS_ENROLL_START[] = {
|
||||
R.id.fingerprint_sensor_location,
|
||||
R.id.fingerprint_progress_bar
|
||||
};
|
||||
|
||||
private static final int VIEWS_ENROLL_PROGRESS[] = {
|
||||
R.id.fingerprint_animator,
|
||||
R.id.fingerprint_progress_bar
|
||||
};
|
||||
|
||||
private static final int VIEWS_ENROLL_FINISH[] = {
|
||||
R.id.fingerprint_enroll_button_area,
|
||||
R.id.fingerprint_in_app_indicator,
|
||||
R.id.fingerprint_enroll_button_add,
|
||||
R.id.fingerprint_enroll_button_next
|
||||
};
|
||||
|
||||
enum Stage {
|
||||
EnrollingOnboarding(R.string.security_settings_fingerprint_enroll_onboard_title,
|
||||
R.string.security_settings_fingerprint_enroll_onboard_message,
|
||||
VIEWS_ENROLL_ONBOARD),
|
||||
EnrollingStart(R.string.security_settings_fingerprint_enroll_start_title,
|
||||
R.string.security_settings_fingerprint_enroll_start_message,
|
||||
VIEWS_ENROLL_START),
|
||||
EnrollingRepeat(R.string.security_settings_fingerprint_enroll_repeat_title,
|
||||
R.string.security_settings_fingerprint_enroll_repeat_message,
|
||||
VIEWS_ENROLL_PROGRESS),
|
||||
EnrollingFinish(R.string.security_settings_fingerprint_enroll_finish_title,
|
||||
R.string.security_settings_fingerprint_enroll_finish_message,
|
||||
VIEWS_ENROLL_FINISH);
|
||||
|
||||
Stage(int title, int message, int[] enabledViewIds) {
|
||||
this.title = title;
|
||||
this.message = message;
|
||||
this.enabledViewIds = enabledViewIds;
|
||||
}
|
||||
|
||||
public int title;
|
||||
public int message;
|
||||
public int[] enabledViewIds;
|
||||
};
|
||||
|
||||
void updateStage(Stage stage) {
|
||||
if (DEBUG) Log.v(TAG, "updateStage(" + stage.toString() + ")");
|
||||
|
||||
// Show/hide views
|
||||
for (int i = 0; i < MANAGED_VIEWS.length; i++) {
|
||||
mContentView.findViewById(MANAGED_VIEWS[i]).setVisibility(View.INVISIBLE);
|
||||
}
|
||||
for (int i = 0; i < stage.enabledViewIds.length; i++) {
|
||||
mContentView.findViewById(stage.enabledViewIds[i]).setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
setTitleMessage(stage.title);
|
||||
setMessage(stage.message);
|
||||
|
||||
if (mStage != stage) {
|
||||
onStageChanged(stage);
|
||||
mStage = stage;
|
||||
}
|
||||
}
|
||||
|
||||
private void startFingerprintAnimator() {
|
||||
AnimationDrawable drawable = (AnimationDrawable) mFingerprintAnimator.getDrawable();
|
||||
drawable.start();
|
||||
}
|
||||
|
||||
private void stopFingerprintAnimator() {
|
||||
AnimationDrawable drawable = (AnimationDrawable) mFingerprintAnimator.getDrawable();
|
||||
drawable.stop();
|
||||
drawable.setLevel(0);
|
||||
}
|
||||
|
||||
private void onStageChanged(Stage stage) {
|
||||
// Update state
|
||||
switch (stage) {
|
||||
case EnrollingOnboarding:
|
||||
mEnrollmentSteps = -1;
|
||||
mEnrolling = false;
|
||||
break;
|
||||
|
||||
case EnrollingStart:
|
||||
mEnrollmentSteps = -1;
|
||||
mFingerprintManager.startListening(mReceiver);
|
||||
mFingerprintManager.enroll(ENROLL_TIMEOUT);
|
||||
mProgressBar.setProgress(0);
|
||||
mEnrolling = true;
|
||||
startFingerprintAnimator(); // XXX hack - this should follow fingerprint detection
|
||||
break;
|
||||
|
||||
case EnrollingRepeat:
|
||||
break;
|
||||
|
||||
case EnrollingFinish:
|
||||
stopFingerprintAnimator(); // XXX hack - this should follow fingerprint detection
|
||||
mFingerprintManager.stopListening();
|
||||
mEnrolling = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
mFingerprintManager.stopListening();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelEnrollment() {
|
||||
if (mEnrolling) {
|
||||
if (DEBUG) Log.v(TAG, "Cancel enrollment\n");
|
||||
mFingerprintManager.enrollCancel();
|
||||
mEnrolling = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
// Do a little cleanup
|
||||
cancelEnrollment();
|
||||
mFingerprintManager.stopListening();
|
||||
}
|
||||
|
||||
private void updateProgress(int progress) {
|
||||
if (DEBUG) Log.v(TAG, "Progress: " + progress);
|
||||
if (mVibrator != null) {
|
||||
mVibrator.vibrate(100, new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build());
|
||||
}
|
||||
if (mProgressAnim != null) {
|
||||
mProgressAnim.cancel();
|
||||
}
|
||||
ObjectAnimator anim = ObjectAnimator.ofInt(mProgressBar, "progress",
|
||||
mProgressBar.getProgress(), progress);
|
||||
anim.addListener(mProgressAnimationListener);
|
||||
anim.start();
|
||||
mProgressAnim = anim;
|
||||
}
|
||||
|
||||
private void setMessage(int id) {
|
||||
if (id != 0) mMessageText.setText(id);
|
||||
}
|
||||
|
||||
private void setTitleMessage(int title) {
|
||||
if (title != 0) mTitleText.setText(title);
|
||||
}
|
||||
|
||||
private FingerprintManagerReceiver mReceiver = new FingerprintManagerReceiver() {
|
||||
public void onEnrollResult(int fingerprintId, int remaining) {
|
||||
if (DEBUG) Log.v(TAG, "onEnrollResult(id=" + fingerprintId + ", rem=" + remaining);
|
||||
if (mEnrollmentSteps == -1) {
|
||||
mEnrollmentSteps = remaining;
|
||||
updateStage(Stage.EnrollingRepeat);
|
||||
}
|
||||
if (remaining >= 0) {
|
||||
int progress = Math.max(0, mEnrollmentSteps + 1 - remaining);
|
||||
updateProgress(100*progress / (mEnrollmentSteps + 1));
|
||||
// Treat fingerprint like a touch event
|
||||
mPowerManager.userActivity(SystemClock.uptimeMillis(),
|
||||
PowerManager.USER_ACTIVITY_EVENT_OTHER,
|
||||
PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS);
|
||||
}
|
||||
}
|
||||
|
||||
public void onError(int error) {
|
||||
switch(error) {
|
||||
case FingerprintManager.FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
|
||||
setMessage(R.string.fingerprint_error_unable_to_process);
|
||||
break;
|
||||
case FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE:
|
||||
setMessage(R.string.fingerprint_error_hw_not_available);
|
||||
break;
|
||||
case FingerprintManager.FINGERPRINT_ERROR_NO_SPACE:
|
||||
setMessage(R.string.fingerprint_error_no_space);
|
||||
break;
|
||||
case FingerprintManager.FINGERPRINT_ERROR_TIMEOUT:
|
||||
setMessage(R.string.fingerprint_error_timeout);
|
||||
break;
|
||||
case FingerprintManager.FINGERPRINT_ERROR_NO_RECEIVER:
|
||||
Log.w(TAG, "Receiver not registered");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void onRemoved(int fingerprintId) {
|
||||
if (DEBUG) Log.v(TAG, "onRemoved(id=" + fingerprintId + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProcessed(int fingerprintId) {
|
||||
if (DEBUG) Log.v(TAG, "onProcessed(id=" + fingerprintId + ")");
|
||||
}
|
||||
|
||||
public void onAcquired(int scanInfo) {
|
||||
int msgId = 0;
|
||||
startFingerprintAnimator();
|
||||
switch(scanInfo) {
|
||||
case FingerprintManager.FINGERPRINT_ACQUIRED_GOOD:
|
||||
break;
|
||||
case FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
|
||||
msgId = R.string.fingerprint_acquired_imager_dirty;
|
||||
break;
|
||||
case FingerprintManager.FINGERPRINT_ACQUIRED_TOO_SLOW:
|
||||
msgId = R.string.fingerprint_acquired_too_fast;
|
||||
break;
|
||||
case FingerprintManager.FINGERPRINT_ACQUIRED_TOO_FAST:
|
||||
msgId = R.string.fingerprint_acquired_too_slow;
|
||||
break;
|
||||
case FingerprintManager.FINGERPRINT_ACQUIRED_PARTIAL:
|
||||
case FingerprintManager.FINGERPRINT_ACQUIRED_INSUFFICIENT:
|
||||
msgId = R.string.fingerprint_acquired_try_again;
|
||||
break;
|
||||
default:
|
||||
// Try not to be too verbose in the UI. The user just needs to try again.
|
||||
// Log the message so we can dig into the issue if necessary.
|
||||
Log.w(TAG, "Try again because scanInfo was " + scanInfo);
|
||||
msgId = R.string.fingerprint_acquired_try_again;
|
||||
break;
|
||||
}
|
||||
setMessage(msgId);
|
||||
}
|
||||
};
|
||||
|
||||
private boolean runConfirmDeviceCredentials(int request) {
|
||||
if (DEBUG) Log.v(TAG, "runKeyguardConfirmation(" + request + ")");
|
||||
Resources res = getResources();
|
||||
return new ChooseLockSettingsHelper(getActivity(), this)
|
||||
.launchConfirmationActivity(request,
|
||||
res.getText(R.string.master_clear_gesture_prompt),
|
||||
res.getText(R.string.master_clear_gesture_explanation));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST) {
|
||||
if (resultCode == RESULT_FINISHED) {
|
||||
// The lock pin/pattern/password was set. Start enrolling!
|
||||
updateStage(Stage.EnrollingStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
final Activity activity = getActivity();
|
||||
mFingerprintManager = (FingerprintManager)activity
|
||||
.getSystemService(Context.FINGERPRINT_SERVICE);
|
||||
mVibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
mPowerManager = (PowerManager) activity.getSystemService(Context.POWER_SERVICE);
|
||||
|
||||
mContentView = inflater.inflate(R.layout.fingerprint_enroll, null);
|
||||
mTitleText = (TextView) mContentView.findViewById(R.id.fingerprint_enroll_title);
|
||||
mMessageText = (TextView) mContentView.findViewById(R.id.fingerprint_enroll_message);
|
||||
mProgressBar = (ProgressBar) mContentView.findViewById(R.id.fingerprint_progress_bar);
|
||||
mFingerprintAnimator = (ImageView) mContentView.findViewById(R.id.fingerprint_animator);
|
||||
|
||||
final int buttons[] = {
|
||||
R.id.fingerprint_enroll_button_add,
|
||||
R.id.fingerprint_enroll_button_next };
|
||||
for (int i = 0; i < buttons.length; i++) {
|
||||
mContentView.findViewById(buttons[i]).setOnClickListener(this);
|
||||
}
|
||||
|
||||
LockPatternUtils utils = new LockPatternUtils(activity);
|
||||
if (!utils.isSecure()) {
|
||||
// Device doesn't have any security. Set that up first.
|
||||
updateStage(Stage.EnrollingOnboarding);
|
||||
} else {
|
||||
updateStage(Stage.EnrollingStart);
|
||||
}
|
||||
return mContentView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switch(v.getId()) {
|
||||
case R.id.fingerprint_enroll_button_add:
|
||||
updateStage(Stage.EnrollingStart);
|
||||
break;
|
||||
case R.id.fingerprint_enroll_button_next:
|
||||
if (mStage == Stage.EnrollingOnboarding) {
|
||||
launchChooseLock();
|
||||
} else if (mStage == Stage.EnrollingFinish) {
|
||||
getActivity().finish();
|
||||
} else {
|
||||
Log.v(TAG, "No idea what to do next!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void launchChooseLock() {
|
||||
Intent intent = new Intent();
|
||||
intent.setClassName("com.android.settings", ChooseLockGeneric.class.getName());
|
||||
startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST);
|
||||
}
|
||||
}
|
||||
}
|
@@ -41,6 +41,8 @@ import android.provider.SearchIndexableResource;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.SettingNotFoundException;
|
||||
import android.security.KeyStore;
|
||||
import android.service.fingerprint.FingerprintManager;
|
||||
import android.service.fingerprint.FingerprintManager.FingerprintItem;
|
||||
import android.service.trust.TrustAgentService;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
@@ -220,32 +222,12 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
}
|
||||
}
|
||||
|
||||
// Trust Agent preferences
|
||||
// Fingerprint and trust agents
|
||||
PreferenceGroup securityCategory = (PreferenceGroup)
|
||||
root.findPreference(KEY_SECURITY_CATEGORY);
|
||||
if (securityCategory != null) {
|
||||
final boolean hasSecurity = mLockPatternUtils.isSecure();
|
||||
ArrayList<TrustAgentComponentInfo> agents =
|
||||
getActiveTrustAgents(getPackageManager(), mLockPatternUtils);
|
||||
for (int i = 0; i < agents.size(); i++) {
|
||||
final TrustAgentComponentInfo agent = agents.get(i);
|
||||
Preference trustAgentPreference =
|
||||
new Preference(securityCategory.getContext());
|
||||
trustAgentPreference.setKey(KEY_TRUST_AGENT);
|
||||
trustAgentPreference.setTitle(agent.title);
|
||||
trustAgentPreference.setSummary(agent.summary);
|
||||
// Create intent for this preference.
|
||||
Intent intent = new Intent();
|
||||
intent.setComponent(agent.componentName);
|
||||
intent.setAction(Intent.ACTION_MAIN);
|
||||
trustAgentPreference.setIntent(intent);
|
||||
// Add preference to the settings menu.
|
||||
securityCategory.addPreference(trustAgentPreference);
|
||||
if (!hasSecurity) {
|
||||
trustAgentPreference.setEnabled(false);
|
||||
trustAgentPreference.setSummary(R.string.disabled_because_no_backup_security);
|
||||
}
|
||||
}
|
||||
maybeAddFingerprintPreference(securityCategory);
|
||||
addTrustAgentSettings(securityCategory);
|
||||
}
|
||||
|
||||
// lock after preference
|
||||
@@ -347,6 +329,58 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
return root;
|
||||
}
|
||||
|
||||
private void maybeAddFingerprintPreference(PreferenceGroup securityCategory) {
|
||||
FingerprintManager fpm = (FingerprintManager) getActivity().getSystemService(
|
||||
Context.FINGERPRINT_SERVICE);
|
||||
if (!fpm.isHardwareDetected()) {
|
||||
Log.v(TAG, "No fingerprint hardware detected!!");
|
||||
return;
|
||||
}
|
||||
Preference fingerprintPreference = new Preference(securityCategory.getContext());
|
||||
fingerprintPreference.setKey(KEY_TRUST_AGENT);
|
||||
fingerprintPreference.setTitle(R.string.security_settings_fingerprint_preference_title);
|
||||
Intent intent = new Intent();
|
||||
List<FingerprintItem> items = fpm.getEnrolledFingerprints();
|
||||
int fingerprintCount = items.size();
|
||||
if (fingerprintCount > 0) {
|
||||
fingerprintPreference.setSummary(getResources().getQuantityString(
|
||||
R.plurals.security_settings_fingerprint_preference_summary,
|
||||
fingerprintCount, fingerprintCount));
|
||||
// TODO: Launch fingerprintSettings instead...
|
||||
intent.setClassName("com.android.settings", FingerprintEnroll.class.getName());
|
||||
} else {
|
||||
// No fingerprints registered, launch directly into fingerprint enrollment wizard
|
||||
intent.setClassName("com.android.settings", FingerprintEnroll.class.getName());
|
||||
}
|
||||
fingerprintPreference.setIntent(intent);
|
||||
securityCategory.addPreference(fingerprintPreference);
|
||||
}
|
||||
|
||||
private void addTrustAgentSettings(PreferenceGroup securityCategory) {
|
||||
final boolean hasSecurity = mLockPatternUtils.isSecure();
|
||||
ArrayList<TrustAgentComponentInfo> agents =
|
||||
getActiveTrustAgents(getPackageManager(), mLockPatternUtils);
|
||||
for (int i = 0; i < agents.size(); i++) {
|
||||
final TrustAgentComponentInfo agent = agents.get(i);
|
||||
Preference trustAgentPreference =
|
||||
new Preference(securityCategory.getContext());
|
||||
trustAgentPreference.setKey(KEY_TRUST_AGENT);
|
||||
trustAgentPreference.setTitle(agent.title);
|
||||
trustAgentPreference.setSummary(agent.summary);
|
||||
// Create intent for this preference.
|
||||
Intent intent = new Intent();
|
||||
intent.setComponent(agent.componentName);
|
||||
intent.setAction(Intent.ACTION_MAIN);
|
||||
trustAgentPreference.setIntent(intent);
|
||||
// Add preference to the settings menu.
|
||||
securityCategory.addPreference(trustAgentPreference);
|
||||
if (!hasSecurity) {
|
||||
trustAgentPreference.setEnabled(false);
|
||||
trustAgentPreference.setSummary(R.string.disabled_because_no_backup_security);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if a there is a Slot that has Icc.
|
||||
*/
|
||||
private boolean isSimIccReady() {
|
||||
|